* RFD: best way to automatically rewrite a git DAG as a linear history? @ 2010-02-18 2:35 Jon Seymour 2010-02-18 5:11 ` Jeff King 0 siblings, 1 reply; 11+ messages in thread From: Jon Seymour @ 2010-02-18 2:35 UTC (permalink / raw) To: Git Mailing List Does the git toolset currently support rewriting a restricted git DAG as a linear history in a completely automated way? I understand that git rebase --root will attempt to rebase a DAG, but as far as I can tell any conflicts that occur during the rebase require a manual intervention to correct. My goal is a completely automated rewrite. I guess some might be sceptical that a sane automated rewrite is impossible, but I am insane enough to think it might actually be possible. I have prototype that implements an algorithm that does this [ for a restricted class of DAG of interest to me ], so I can't be completely insane, but if other people have already knocked the corners of this particular wheel, I'd be interested to learn of their efforts. Regards. jon ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFD: best way to automatically rewrite a git DAG as a linear history? 2010-02-18 2:35 RFD: best way to automatically rewrite a git DAG as a linear history? Jon Seymour @ 2010-02-18 5:11 ` Jeff King 2010-02-18 18:38 ` Avery Pennarun 2010-02-19 1:04 ` Jon Seymour 0 siblings, 2 replies; 11+ messages in thread From: Jeff King @ 2010-02-18 5:11 UTC (permalink / raw) To: Jon Seymour; +Cc: Git Mailing List On Thu, Feb 18, 2010 at 01:35:07PM +1100, Jon Seymour wrote: > Does the git toolset currently support rewriting a restricted git DAG > as a linear history in a completely automated way? Not really. It's a hard problem in the general case. Consider a history like: B / \ A D \ / C That is, two branches fork, each make a commit, and then merge. You want something like: A--B--C' If there is a merge conflict when making D, then you know that B and C conflict. In this simple case, you can apply the same conflict resolution used in D to the creation of C' (in other words, you use the combined tree state given in D as the tree for C'). But what if C is a string of commits? Some of the conflict resolution in D will be applicable to some of the conflicts you will encounter when rebasing C, but you don't know which. One simple strategy would be to squash all side-branch development into a single commit. So you would turn: B--C--D / \ A H \ / E--F--G into A--B--C--D--X where X has the same tree as H, but contains all of the commit messages of E, F, and G. You are of course losing quite a bit of information there, but you haven't really told us what your use case is, so I don't know whether that's unacceptable or not. -Peff ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFD: best way to automatically rewrite a git DAG as a linear history? 2010-02-18 5:11 ` Jeff King @ 2010-02-18 18:38 ` Avery Pennarun 2010-02-19 1:04 ` Jon Seymour 1 sibling, 0 replies; 11+ messages in thread From: Avery Pennarun @ 2010-02-18 18:38 UTC (permalink / raw) To: Jeff King; +Cc: Jon Seymour, Git Mailing List On Thu, Feb 18, 2010 at 12:11 AM, Jeff King <peff@peff.net> wrote: > One simple strategy would be to squash all side-branch development into > a single commit. Something like this (replace MY_START_BRANCH with your starting branch, and do this in a clone of your repository so you don't destroy anything by accident): parent="" git rev-list --first-parent --reverse | while read commit; do if [ -z "$parent" ]; then git checkout -f $commit git clean -fdx else git diff $parent $commit | git apply --index git commit -C $commit fi parent=$commit done Have fun, Avery ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFD: best way to automatically rewrite a git DAG as a linear history? 2010-02-18 5:11 ` Jeff King 2010-02-18 18:38 ` Avery Pennarun @ 2010-02-19 1:04 ` Jon Seymour 2010-02-19 3:13 ` Avery Pennarun 1 sibling, 1 reply; 11+ messages in thread From: Jon Seymour @ 2010-02-19 1:04 UTC (permalink / raw) To: Jeff King; +Cc: Git Mailing List, apenwarr Jeff, The use case is extracting a patch series from a developer who has been frequently pulling (and thus merging) with an upstream but has not successfully delivered anything upstream. I want to be able to unpick the upstream merge history and reconstruct a reasonable faithful representation of the developer's edits in a linear series of commits that can then be reviewed, edited, squashed, re-ordered as necessary as part of integration activities. I also want to handle the cases where a (bad) upstream rebase occurred or the developer has (incorrectly) merged with history from a peer that has also not been integrated upstream This places a useful constraint on the DAG rewrite that I need to do - I can restrict the rewrite to the reverse of linear traversal from the developer's current head back to the first commit that has not been integrated upstream. Avery's script almost does what I need, except the rewritten diffs corresponding to the merge commits introduces unnecessary noise (from upstream deltas) in the series and potentially complicate eventual merges of the linear history back into the upstream. What I am doing at the moment is doing a piece-wise replacement of each merge with an equivalent rebase from the other branch of the merge, starting with the oldest merge. While doing this, there arises the possibility of a merge conflict between a commit made by the developer and a commit on the other branch of the merge. For my purposes, at the point of the pick where the conflict is detected, the conflicted blob is resolved in favour of the developer's blob. This technically introduces an error into the history since resolving the conflict in this way is almost certainly not correct. However, it does mean that all subsequent picks on that segment for that blob will apply correctly. At the end of each the rewrite of each segment, the conflicted blob is replaced with the result of the developer's original merge so that the introduced error is then corrected with a perfect correction (assuming the developer did a sane merge in the first place). In effect, each conflict introduces two deltas into the history - one to enable the subsequent picks to apply cleanly and one to reapply the developer's original resolution of the conflict. This approach has several consequences: * the rewrite is completely automated * by construction, the tree will be consistent with developer's tree at the commit corresponding to each merge the developer did. * there is one commit in the rewritten history for each commit in the original history + two commits for each auto-resolved conflict (one that introduces the error to and one that later corrects it using the developer's merge) It is true that the rewritten history does contain periods where the intervening commits are not strictly consistent (periods between the error introducing delta and its subsequent correction), but if this is really important, these can be resolved with an interactive rebase as required. On the otherhand, rewritten history will be fully consistent at well-specified points - particularly at commits corresponding to the original merge commits and on any segment that was not affected by a merge conflict. Regards, jon seymour. On 18/02/2010, at 16:11, Jef King <peff@peff.net> wrote: > On Thu, Feb 18, 2010 at 01:35:07PM +1100, Jon Seymour wrote: > >> Does the git toolset currently support rewriting a restricted git DAG >> as a linear history in a completely automated way? > > Not really. It's a hard problem in the general case. Consider a > history > like: > > B > / \ > A D > \ / > C > > That is, two branches fork, each make a commit, and then merge. You > want > something like: > > A--B--C' > > If there is a merge conflict when making D, then you know that B and C > conflict. In this simple case, you can apply the same conflict > resolution used in D to the creation of C' (in other words, you use > the > combined tree state given in D as the tree for C'). But what if C is a > string of commits? Some of the conflict resolution in D will be > applicable to some of the conflicts you will encounter when rebasing > C, > but you don't know which. > > One simple strategy would be to squash all side-branch development > into > a single commit. So you would turn: > > B--C--D > / \ > A H > \ / > E--F--G > > into > > A--B--C--D--X > > where X has the same tree as H, but contains all of the commit > messages > of E, F, and G. > > You are of course losing quite a bit of information there, but you > haven't really told us what your use case is, so I don't know whether > that's unacceptable or not. > > -Peff ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFD: best way to automatically rewrite a git DAG as a linear history? 2010-02-19 1:04 ` Jon Seymour @ 2010-02-19 3:13 ` Avery Pennarun 2010-02-19 7:29 ` Jon Seymour 0 siblings, 1 reply; 11+ messages in thread From: Avery Pennarun @ 2010-02-19 3:13 UTC (permalink / raw) To: Jon Seymour; +Cc: Jeff King, Git Mailing List On Thu, Feb 18, 2010 at 8:04 PM, Jon Seymour <jon.seymour@gmail.com> wrote: > Avery's script almost does what I need, except the rewritten diffs > corresponding to the merge commits introduces unnecessary noise (from > upstream deltas) in the series and potentially complicate eventual > merges of the linear history back into the upstream. You're never going to get the "linear" history merged back upstream until you fix the inconsistencies. At least, no sensible upstream should accept the patches. Using the linearization mechanism you propose, you end up producing a false history: one in which, other than at certain checkpoints, the code doesn't even work. What's the point of such a history? It neither reflects the true development history (ie. pre-linearization) nor a more useful, idealized version of history (ie. one that compiles at every point and adds features in a rational order and is useful for git bisect). It doesn't even provide something useful for patch review, since half your patches will have randomly-selected conflict resolutions (ie. changes to unrelated code that never should have changed) thrown in. You'd be better off reviewing patches from the original history, and just ignoring merge commits, which is what 'git format-patch' or just 'git log -p' would do automatically. The result is also still not suitable for submission upstream: the sync points (where the files actually match what the developer had in his tree) are the only places where the code is even likely to compile, and yet they *also* include all the code brought in by prior merges, which you already said include code that shouldn't go upstream. The linearization script I gave you at least has these interesting characteristics: - If the original history compiled at every point, then the linearized history does too. - It is an accurate representation of the successive states of the tree experienced by the original developer. - You can use 'git rebase' to incrementally rearrange and combine patches until they make enough sense to submit upstream. - It is easy to separate out merges (which usually don't need patch review) from individual patches (which do). - If some merges added useless code, you can remove them completely with rebase by just removing a single patch from the list. Of course, even with this script, it will still take work (rebasing) to produce code that's polished and ready to go upstream. But I'm not sure there's a way to automate that without producing interim versions that are much, much worse. Have fun, Avery ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFD: best way to automatically rewrite a git DAG as a linear history? 2010-02-19 3:13 ` Avery Pennarun @ 2010-02-19 7:29 ` Jon Seymour 2010-02-19 20:20 ` Avery Pennarun 0 siblings, 1 reply; 11+ messages in thread From: Jon Seymour @ 2010-02-19 7:29 UTC (permalink / raw) To: Avery Pennarun; +Cc: Jeff King, Git Mailing List On Fri, Feb 19, 2010 at 2:13 PM, Avery Pennarun <apenwarr@gmail.com> wrote: > On Thu, Feb 18, 2010 at 8:04 PM, Jon Seymour <jon.seymour@gmail.com> wrote: > > Using the linearization mechanism you propose, you end up producing a > false history: one in which, other than at certain checkpoints, the > code doesn't even work. What's the point of such a history? It > neither reflects the true development history (ie. pre-linearization) > nor a more useful, idealized version of history (ie. one that compiles > at every point and adds features in a rational order and is useful for > git bisect). If there are no merge conflicts in the original history, then there will be no merge conflicts in the rewritten history, and therefore no error deltas. The point of creating the linearization of this kind is that if there are no merge conflicts, it flattens the hierarchy in a form that is immediately rebaseable and will faithfully represent the work the developer would have done if they had decided to rebase at each merge instead of merging. If there are merge conflicts, then it produces a history that indicates the extent the merge conflict rectification that will be needed which then allows you to decide whether you want to attempt the rebase. If you decide to rebase, then it should just be a question of deleting the delta commits and fixing the merge conflicts as they crop up. My contention is that most of the text diffs in the rewritten history (with the exception of the error deltas) will actually represent the intent of the developers original changes although until the rectification work is done the commit sequences bounded by error deltas would not be usable for git bisect, compiles or any other purpose that requires an intact tree. In the no conflict case, it is not clear to me that the history resulting from your script is immediately rebaseable, precisely because of the presence of the merge commits [ feel free to correct me if I am wrong about that ] . With my approach, the merge commits dissolve away - there is nothing to edit. > > It doesn't even provide something useful for patch review, since half > your patches will have randomly-selected conflict resolutions (ie. > changes to unrelated code that never should have changed) thrown in. > You'd be better off reviewing patches from the original history, and > just ignoring merge commits, which is what 'git format-patch' or just > 'git log -p' would do automatically. The conflict resolutions are far from random. They are precisely chosen to reconstruct the blob in such a way that all subsequent picks in the same path segment apply cleanly. This is a deliberate choice because we know that conflict will be resolved eventually. We are temporarily deferring correctness to allow us to automatically proceed with a speculative rewrite of the merge history as a rebase history. The extent of incorrectness in the history is well delimited and well understood. > > The result is also still not suitable for submission upstream: the > sync points (where the files actually match what the developer had in > his tree) are the only places where the code is even likely to > compile, and yet they *also* include all the code brought in by prior > merges, which you already said include code that shouldn't go > upstream. I agree it is not suitable for many purposes. I contend that what it allows one to do is rewrite the merge history as a rebase history in a form that allows the merge conflict resolutions to be deferred. In the no conflict case, the linearisation is immediately usable (with no further edits) as a rebase source. > > The linearization script I gave you at least has these interesting > characteristics: > > - If the original history compiled at every point, then the linearized > history does too. > > - It is an accurate representation of the successive states of the > tree experienced by the original developer. > > - You can use 'git rebase' to incrementally rearrange and combine > patches until they make enough sense to submit upstream. > > - It is easy to separate out merges (which usually don't need patch > review) from individual patches (which do). > > - If some merges added useless code, you can remove them completely > with rebase by just removing a single patch from the list. > > Of course, even with this script, it will still take work (rebasing) > to produce code that's polished and ready to go upstream. But I'm not > sure there's a way to automate that without producing interim versions > that are much, much worse. > > Have fun, > > Avery > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFD: best way to automatically rewrite a git DAG as a linear history? 2010-02-19 7:29 ` Jon Seymour @ 2010-02-19 20:20 ` Avery Pennarun 2010-02-20 2:25 ` Jon Seymour 0 siblings, 1 reply; 11+ messages in thread From: Avery Pennarun @ 2010-02-19 20:20 UTC (permalink / raw) To: Jon Seymour; +Cc: Jeff King, Git Mailing List On Fri, Feb 19, 2010 at 2:29 AM, Jon Seymour <jon.seymour@gmail.com> wrote: > If there are no merge conflicts in the original history, then there > will be no merge conflicts in the rewritten history, and therefore no > error deltas. I'm just worried that this is a bit misleading. Just because there are no conflicts at the end doesn't mean these generated interim versions ever compiled or worked, does it? Imagine that I have some code: f(a); g(x); I change it so that f takes an extra parameter f(a, b); g(x); Then I merge in someone else's branch that adds an extra parameter to function g, but hasn't changed f: f(a); g(x, y); The merge causes a conflict, which I resolve in the obvious way: f(a, b); g(x, y) Now I linearize it in the way you propose, removing the "unnecessary" merges but keeping the developer's conflict resolutions. What I end up with is the last code segment above - but I *don't* have the rest of the patch that added the extra parameter to g. So my conflict resolution is wrong for the code that remains. And the delta fixup doesn't show that there was anything weird. Unless I've misunderstood something, you've thrown away the *advantage* that was autodetection of conflicts, in favour of having to eyeball it. I'm not sure there's an advantage there. > In the no conflict case, it is not clear to me that the history > resulting from your script is immediately rebaseable, precisely > because of the presence of the merge commits [ feel free to correct me > if I am wrong about that ] . With my approach, the merge commits > dissolve away - there is nothing to edit. I'm pretty sure that in the absence of conflicts, you could rebase -i my linearization and just remove the merge commits by hand, and things should go pretty smoothly. Or in the simplest cases (ie. the merged code is identical), rebase would notice that the merge patches have already been applied, and simply throw them away. In any case, I guess if what you're doing works for you, then go for it. But in that case I'm not sure why you asked your original question; what about your current method *doesn't* do what you want? If it's just a question of always auto-resolving conflicts using the local merge resolution, you might be interested in -Xours and -Xtheirs: http://n2.nabble.com/PATCH-0-8-The-return-of-Xours-Xtheirs-Xsubtree-dir-td4069081.html If you're looking for more general suggestions about what to do when untangling a developer's horribly over-merged tree, you may want to consider a simple but inelegant solution that I've used myself sometimes: just squash the entire diff from upstream to developer's version into a single commit, then rip it apart again by hand. In my experience, developers who make messes of merges also don't divide their commits into sensible fragments in the first place, so re-dividing them yourself afterward is actually the fastest route to sanity. Hope this helps. Have fun, Avery ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFD: best way to automatically rewrite a git DAG as a linear history? 2010-02-19 20:20 ` Avery Pennarun @ 2010-02-20 2:25 ` Jon Seymour 2010-02-20 3:05 ` Avery Pennarun 0 siblings, 1 reply; 11+ messages in thread From: Jon Seymour @ 2010-02-20 2:25 UTC (permalink / raw) To: Avery Pennarun; +Cc: Jeff King, Git Mailing List On Sat, Feb 20, 2010 at 7:20 AM, Avery Pennarun <apenwarr@gmail.com> wrote: > On Fri, Feb 19, 2010 at 2:29 AM, Jon Seymour <jon.seymour@gmail.com> wrote: >> If there are no merge conflicts in the original history, then there >> will be no merge conflicts in the rewritten history, and therefore no >> error deltas. > > I'm just worried that this is a bit misleading. Just because there > are no conflicts at the end doesn't mean these generated interim > versions ever compiled or worked, does it? > > ... example elided > > Now I linearize it in the way you propose, removing the "unnecessary" > merges but keeping the developer's conflict resolutions. What I end > up with is the last code segment above - but I *don't* have the rest > of the patch that added the extra parameter to g. So my conflict > resolution is wrong for the code that remains. And the delta fixup > doesn't show that there was anything weird. > The thing is, if I linearised in the way I proposed, there would be a conflict during the rebase of one branch of the merge onto the other - so the conflict would be still be there. However, what happens is that rather than stopping to manually correct the conflict, I compensate for the conflict by introducing a patch that restores the file to state it was in when the conflicting commit was originally committed. This guarantees that all future picks for that file will apply correctly. You are entirely correct that the compensated file is no longer consistent with the rest of the tree at that point in the history. However, once the rewritten history passes the original merge, the consistency of the tree will be restored (reason: by design the rewritten history always restores the state of the tree the point in the rewritten history that matches a merge in the original history). The inconsistencies are thus limited in scope [ and, as you will well see, well delimited ] > Unless I've misunderstood something, you've thrown away the > *advantage* that was autodetection of conflicts, in favour of having > to eyeball it. I'm not sure there's an advantage there. > The conflicts are detected and clearly marked in the history. What I have done is simply defer the resolution of the conflicts to a point of my later choosing so that I can continue with the linearisation process automatically. One nice consequence of my linearisation is that (even in the presence of compensations) any diff between two points in the linearized history will only show files touched by the history - not files that changed in the upstream branch. True, some of these diffs will produce nonsensical results (in particular diffs within a pair of compensating deltas are not necessarily useful, nor are diffs that include one compensation but not the other). However, diffs across histories that do include both compensations will be sensible. An example: A-B-C-D-E-F-G-H \ \ \ \-M-N-P-Q-R-S-T (Merge at Q between P and E, merge at T between S and H) Suppose a change made in C conflicts with a change made in N. This was eventually resolved in the merge commit Q. There were no conflicts in subsequent histories after E and Q (e.g. the merge at T was clean) My linearisation would first rebase on E. A B C D E M' e(^N) N' P' e(Q^) R' S' T' e(^N) returns the state of conflicted files to the point they were before N was applied. q(Q^) returns the state of conflicted files to the point the were after the merge at Q. The conflict between C and N forced me to backtrack the conflicted files to the state they were before N. This is done by the compensation e(^N). The commits N and P are then repicked and are guaranteed to succeed (by definition - the conflicted files are now in the same state as they originally were). A reverse compensation e(Q^) is applied to ensure that R' sees the tree as it was at Q. The algorithm then rebases this history onto H. A B C D E F G H M'' e(^e(^N)) N'' P'' e(e(Q^)^) R'' S'' The following is true: * the tree at e(e(Q^)^) is identical to the state of the tree at Q * the tree at S'' is identical to the state of the tree at T * the trees at M'' R'' S'' are consistent with the states that would have been if rebases had been performed at Q and T with the same conflict resolution outcomes. * the trees at N'' P'' are internally inconsistent because some (but not all) files have 'slipped backwards in time' * the diff between M'' and R'' will be the equivalent to the diff between M and R * diffs between any points with M'' and S'' will only show files touched by edits at M, N, P, R, S or the merge Q (the intermediate rebasing on E and H dissolves the merge at T) * the series e(^e(^N)) N'' P'' e(e(Q^)^) could be squashed into a single commit that would correspond to the edits done in N and P and the conflict resolution done in Q. * the merge history ^A T has been automatically rewritten as a rebase history ^H S'' An interesting possibility would be to squash e(^e(^N)) N'' e(e(Q^)^) as N''' and then edit P'' to be consistent with a new base, N'''. (In fact, in this case P'' would simply be the diff between N''' and Q - it gets more complicated if there is a series of intervening commits between N and P). If this worked (and there is no guarantee it would), then it would have the effect of folding the conflict resolution with C performed at Q into a re-edited commit N''' which is where it would have occurred had ^A N been rebased on C in the first place. >> In the no conflict case, it is not clear to me that the history >> resulting from your script is immediately rebaseable, precisely >> because of the presence of the merge commits [ feel free to correct me >> if I am wrong about that ] . With my approach, the merge commits >> dissolve away - there is nothing to edit. > > I'm pretty sure that in the absence of conflicts, you could rebase -i > my linearization and just remove the merge commits by hand, and things > should go pretty smoothly. Or in the simplest cases (ie. the merged > code is identical), rebase would notice that the merge patches have > already been applied, and simply throw them away. > > In any case, I guess if what you're doing works for you, then go for > it. But in that case I'm not sure why you asked your original > question; what about your current method *doesn't* do what you want? > Part of the reason I asked is that I was wondering whether someone had hit upon this solution already, and if they had, I'd take advantage of it. My discussions with you have certainly helped me think about and articulate the nature of the inconsistencies that are introduced, so that has helped too. > If it's just a question of always auto-resolving conflicts using the > local merge resolution, you might be interested in -Xours and > -Xtheirs: > http://n2.nabble.com/PATCH-0-8-The-return-of-Xours-Xtheirs-Xsubtree-dir-td4069081.html > > If you're looking for more general suggestions about what to do when > untangling a developer's horribly over-merged tree, you may want to > consider a simple but inelegant solution that I've used myself > sometimes: just squash the entire diff from upstream to developer's > version into a single commit, then rip it apart again by hand. In my > experience, developers who make messes of merges also don't divide > their commits into sensible fragments in the first place, so > re-dividing them yourself afterward is actually the fastest route to > sanity. Yep, I agree that's not a bad option in many cases. It's pragmatic, though rebuilding a history where the tree is internally consistent at each point is a somewhat tedious. Linearisation at least holds out the possibility of restoring consistency if you really want it for some reason but allows you to defer the costs of doing so if you don't really need it. > > Hope this helps. > It has. > Have fun, I will - I have created a github project called hammer where I will make a realisation of these ideas available for evaluation at some point. git@github.com:jonseymour/hammer.git (A hammer is, of course, a reasonably good tool for making things flat although it does tend to break things along the way). jon. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFD: best way to automatically rewrite a git DAG as a linear history? 2010-02-20 2:25 ` Jon Seymour @ 2010-02-20 3:05 ` Avery Pennarun 2010-02-21 23:04 ` Jon Seymour 0 siblings, 1 reply; 11+ messages in thread From: Avery Pennarun @ 2010-02-20 3:05 UTC (permalink / raw) To: Jon Seymour; +Cc: Git Mailing List On Fri, Feb 19, 2010 at 9:25 PM, Jon Seymour <jon.seymour@gmail.com> wrote: > (A hammer is, of course, a reasonably good tool for making things flat > although it does tend to break things along the way). Nice analogy. Well, thanks for the clarification and best of luck in your slightly crazy project :) Have fun, Avery ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFD: best way to automatically rewrite a git DAG as a linear history? 2010-02-20 3:05 ` Avery Pennarun @ 2010-02-21 23:04 ` Jon Seymour 2010-02-21 23:18 ` Jon Seymour 0 siblings, 1 reply; 11+ messages in thread From: Jon Seymour @ 2010-02-21 23:04 UTC (permalink / raw) To: Avery Pennarun; +Cc: Git Mailing List On Sat, Feb 20, 2010 at 2:05 PM, Avery Pennarun <apenwarr@gmail.com> wrote: > On Fri, Feb 19, 2010 at 9:25 PM, Jon Seymour <jon.seymour@gmail.com> wrote: >> (A hammer is, of course, a reasonably good tool for making things flat >> although it does tend to break things along the way). > > Nice analogy. Well, thanks for the clarification and best of luck in > your slightly crazy project :) > Thank you - FWIW, it is shaping up very well. In turns out that in cases where the original merge was resolved in favour of the conflict, the compensation can be squashed with the compensated commit - effectively bring the eventual resolution forward in time. This is so, so cool. jon. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: RFD: best way to automatically rewrite a git DAG as a linear history? 2010-02-21 23:04 ` Jon Seymour @ 2010-02-21 23:18 ` Jon Seymour 0 siblings, 0 replies; 11+ messages in thread From: Jon Seymour @ 2010-02-21 23:18 UTC (permalink / raw) To: Avery Pennarun; +Cc: Git Mailing List Sorry, that lacked complete sense: Thank you - FWIW, it is shaping up very well. In turns out that in cases where the original merge was resolved in favour of the _rebased branch_, the compensation can be squashed with the compensated commit - effectively bringing the eventual resolution of the conflict forward in time. jon. ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2010-02-21 23:18 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-02-18 2:35 RFD: best way to automatically rewrite a git DAG as a linear history? Jon Seymour 2010-02-18 5:11 ` Jeff King 2010-02-18 18:38 ` Avery Pennarun 2010-02-19 1:04 ` Jon Seymour 2010-02-19 3:13 ` Avery Pennarun 2010-02-19 7:29 ` Jon Seymour 2010-02-19 20:20 ` Avery Pennarun 2010-02-20 2:25 ` Jon Seymour 2010-02-20 3:05 ` Avery Pennarun 2010-02-21 23:04 ` Jon Seymour 2010-02-21 23:18 ` Jon Seymour
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).