5 ms·
From https://pijul.org/manual/why_pijul.html#patch-commutation https://pijul.org/manual/why_pijul.html#patch-commutation: > In Git, importing just a few commit
by frutiger 7y ago
From https://pijul.org/manual/why_pijul.html#patch-commutation https://pijul.org/manual/why_pijul.html#patch-commutation:
> In Git, importing just a few commits from another branch is called "cherry-picking", and involves changing the identity (the hash) of those commits. This usually works the first time. However, when done again, as the maintainer of a stable branch probably wants to do, this often causes counter-intuitive conflicts.
If you're doing this in git to apply a fix to a master branch and multiple release branches, you're doing it wrong. You should be basing the patches off the merge-base of master and the oldest release branch you wish to land the change into.
If you work this way, you can merge the patch cleanly into all target branches, and this new patch becomes the new merge-base. So you can actually continue to apply new patches without any conflicts.
- mjw1007 7y agoBut you don't want your VCS to dictate your project management. Maybe you want to apply the patch to the main development branch, let people try it there for a while, and then decide which maintained release branches should get the patch.
- frutiger 7y agoYou can actually achieve this by making a new branch at the merge-base, cherry picking the fix from the development branch, then landing this branch into the release and development branch. Git will record the parent commit correctly on both branches but apply no changeset to the development branch, while applying it to the release branch. I admit the above is a bit much for most people.
- pmeunier 7y ago> I admit the above is a bit much for most people. True, but it's not just the UI: this also requires discipline and constant synchronisation in a team. Pijul achieves the same without much discipline.
- mjw1007 7y agoIt's still not ideal. With git's DAG-based "patch model", I think what you'd really want to do is, after making the new branch and cherry-picking the fix, make that new commit a second parent of the original commit (so that it becomes a merge, but its tree doesn't change). I think that would leave the graph with the best representation of what's going on (ie, the same thing as if you'd made the patch from the merge-base in the first place). But git's hash-based system for identifying commits won't let you add new parents.
- frant-hartm 7y agoSome people avoid merges like plague because they hate their commit history looking like a train station. Then you cherry pick and/or rebase.
- frutiger 7y agoI never really understood this philosophy. Separating the graph structure from how you view it is the way to go I think. e.g. `git log --no-merges`.
- frant-hartm 7y agoWhy would I want my history to be a graph in the first place?
- totony 7y agoA graph can be flatten, but a sequence/line can't be expended. More information seems better than less
- kccqzy 7y agoI find that with `--first-parent`, my history looks reasonably linear, assuming the typical workflow of having each merge commit merging a topic branch into master.
- frant-hartm 7y agoYeah that works, if people are disciplined (no merge origin/master into master ...). You don't see individual commits from feature branches though.
- kccqzy 7y agoYes. And code review should enforce that kind of discipline. I am not generally interested in individual commits from feature branches though, but when I do I can easily reveal them when needed.
- pmeunier 7y ago> If you're doing this [..], you're doing it wrong. [..] This is not 100% true (see my answer to the second part below), but the point of Pijul is that you don't need to "do things right" to avoid the potential problems of your version control system. In the end, a version control system is just a tool, not a way of life or a work methodology. Sure, there are example projects where the Git way is the best, but they are quite rare (one example is Software Heritage [1]). > If you work this way, you can merge the patch cleanly into all target branches, and this new patch becomes the new merge-base. So you can actually continue to apply new patches without any conflicts. This is not actually true, and is the whole point of Pijul. In Git, your suggestion works only as long as (1) there is never any conflict, else you need "git rerere", and (2) 3-way merge never runs into a non-associative merge [2]. [1] https://www.softwareheritage.org/ https://www.softwareheritage.org/ [2] https://tahoe-lafs.org/~zooko/badmerge/simple.html https://tahoe-lafs.org/~zooko/badmerge/simple.html
- frutiger 7y ago> This is not actually true, and is the whole point of Pijul. In Git, your suggestion works only as long as (1) there is never any conflict, else you need "git rerere", and (2) 3-way merge never runs into a non-associative merge [2]. Sure, if the two branches have diverged around the location of the patch, there will need to be a merge resolution. Wouldn’t Pijul require the same too?
- pmeunier 7y agoFirst, even though Pijul has branches, patch commutation means that most Git branches are just regular patches in Pijul. > Wouldn’t Pijul require the same too? If you're talking about my point (1) above, the answer to your question is no, because in Pijul, conflicts are resolved by patches, so if a branch has a patch solving a conflict, the conflict cannot come back. So Pijul doesn't need "rerere". If you're talking about my point (2), the answer is also no: non-associative merges happen for bad reasons in Git. By design, Pijul doesn't have them at all.
- frutiger 7y ago