Matt McCutchen <matt@xxxxxxxxxxxxxxxxx> writes: > Rsync presents a unique challenge because it has a number of long-term > feature patches that are maintained and distributed with the main source > code. Furthermore, some of the patches depend on other patches. > ... > 1. How to properly represent the history of an individual branch and > update it when the trunk (or the branch on which it depends) changes. > Right now, Wayne updates the branch by rebasing; unfortunately, if the > trunk changes in such a way that one of the intermediate commits no > longer makes sense, it is impossible to update the branch while > preserving a record that the intermediate commit once existed. I take this to mean a situation like this: * There is a series of patch X Y Z that implements some nicety not present in the mainline yet. This set applies to older codebase at point A. * Newer codebase B does things differently from codebase A and patch X is no longer needed --- IOW, what X achieves on top of A has already been incorporated somewhere between A and B. Applying Y and Z suffices to obtain that nice feature on top of B. .---X---Y---Z .---Y'--Z' / / ---o---A---o---.....---o---B This is natively expressed with git, if your history were like this: .----------X------Y-------Z / \ ---o---A---o---....---M---....---B and you publish Z. People who would want to apply the series to their codebase simply merge Z. The patch dependency of X is captured in the mainline history because the effect of X is incorporated to the mainline as a merge at M. If the point they want to apply the series is older than point M (where patch X becomes unnecessary because of the mainline change), X, Y and Z will be brought in, while people basing on commits newer than M will pull in only Y and Z (because they already have X). But that works only in theory and with a developer with perfect vision. Nobody would be able to forsee that X would become such a crucial change when it is developed. Often you would just create a regular commit M somewhere between A and B that has the effect of X, and later regret that you had made a separate X forked from an earlier A and recorded M as a merge. People use quilt (or guilt) to manage patch stacks for things like this. Having said that, I think you can maintain a single patch series (say the above X-Y-Z) and publish it as a few variants for downloaders as a prefabricated set of branches. Say if you have this (the first picture), you do not create Y'-Z' history (again, M is the point patch X becomes unnecessary, but we live in the real world and it was not recorded as a merge of X into the mainline): .---X---Y---Z / / / ---o---A---o---.....---M---...---o---B and X-Y-Z _is_ what you would maintain and keep tweaking. You can publish Z and people who would want to "apply" the series can cleanly apply X-Y-Z (or merge Z if they are git users). But people who would want to "apply" the series to codebase newer than point M would individually need to resolve conflicts or know X is unneeded for them. To alleviate this, you would publish _another_ commit: .---X---Y---Z / \ / Z' / / ---o---A---o---.....---M---...---o---B That is, you merge Z to newer mainline for them to create Z', and: * publish Z' for git users --- they can merge this to their codebase that is newer than M and they do not have to resolve conflicts you needed to resolve, arising from the overlap between X and M, when you created Z'. * publish diff between M-Z', for non git users who would want to apply it with "patch". You suggested that you would keep rebasing X--Y--Z while improving the long living patch series. You would recreate Z' whenever the series is updated (and rerere will hopefully help you re-resolve the conflicts between X and M automatically). - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html