{"thread":{"id":"57750","subject":"Current state / standard advice for rebasing merges without information loss/re-entry?","startedAt":"2022-04-18T11:56:53Z","lastAt":"2022-04-20T23:54:52Z","messageCount":14,"participants":["Tao Klerks","Philip Oakley","Junio C Hamano","Sergey Organov","Martin von Zweigbergk"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"453804","messageId":"CAPMMpojjs4sjKdN6DAJFSwERdjq9XQgi35CcqkXu7HijadHa1Q@mail.gmail.com","threadId":"57750","inReplyTo":null,"subject":"Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Tao Klerks","fromEmail":"tao@klerks.biz","sentAt":"2022-04-18T11:56:38Z","receivedAt":"2022-04-18T11:56:53Z","isPatch":false,"sender":{"key":"tao@klerks.biz","avatar":"https://avatars.githubusercontent.com/u/531704?v=4"},"body":"Hi folks,\n\nThe discussion around Edmundo Carmona Antoranz's recent \"git replay\"\nproposal ([1]) led me down a rabbit-hole reminding me I really don't\nunderstand where we stand with rebasing merges, and I don't think I'm\nalone.\n\nI understand the standard advice at the moment to be something like:\n---\nUse a recent git client, use the '--rebase-merges' option (avoid the\n--preserve-merges option if you find it), and re-resolve any textual\nand/or semantic conflicts manually (possibly using rerere if you know\nwhat you're doing).\n---\nIs this correct?\n\nThis current state/advice seems... suboptimal, at best, because it\nignores any information encoded in the original merge commit, as\nclearly documented in the help. It will often result in you having to\nresolve conflicts that you already resolved, *where nothing relevant\nto that merge/commit has changed in your rebase*. If you have rerere,\nand you know what you are doing, and you were the one that performed\nthe merge, in this repo, then maybe you're ok; similarly if it's a\nclean merge of course.\n\nElijah Newren describes this problem/opportunity quite carefully in\n[2], and mentions a bunch of WIP that I have a hard time getting my\nhead around.\n\nSimilarly, Sergey Organov refers to a thread/discussion four years ago\n[3], largely involving a debate around two implementations (his and\nthat of Phillip Wood?) that are largely theoretically-equivalent (in a\nmajority of cases), with a lovely explanation of the theory behind the\nproposal by Igor Djordjevic / Buga [4], but that discussion appears to\nhave dried up; I can't tell whether anything came of it, even if only\na manually-usable \"rebase a merge\" script.\n\nFinally, Martin von Zweigbergk mentions his git-like VCS [5] which\nstores conflict data in some kinds of commit as part of a general\n\"working state is always committable and auto-committed\"\nstate-management strategy; I may be misunderstanding something, but I\n*think* the resulting conflict-resolution information ends up being\nreusable in a manner theoretically equivalent to the strategy\ndescribed by Buga as referenced above.\n\nThese kinds of discussions frequently seem to feature git experts\nsaying \"I have a script for my version of this problem\" (Elijah,\nJunio, Johannes Schindelin, ...), or even \"I have a VCS for this\nproblem\" :), but I seem to be too stupid or impatient to dig\nthrough/understand whether or when these things will work for a\nregular joe and how to use them.\n\nThe temptation, obviously(?), is to write a \"rebase a merge\" script to\ndo something like Sergey Organov's V2 proposal referenced above... but\nit feels like I'd be spending a bunch of time and ultimately just\nmaking things worse for the community, rather than better - helping\nmyself based on my (very limited, but still above average)\nunderstanding of merge mechanics, in a way that leaves the general\npublic message / status just as unsatisfactory/unhelpful.\n\nDoes anyone have an existing simpler answer? Ideally I'm looking for\nsomething like:\n---\n* When you have a merge in your history, and you are rebasing, follow\nsteps XXXXXX, involving this publicly available gist, or contrib\nscript, or experimental flag, and it will probably do what you want.\nIf there is a (new) conflict when rebasing the merge commit, you can\nexpect conflicts to be presented as YYYYY, because rebasing a merge in\nthis \"informed\" way can fundamentally involve multiple different\nsteps/phases of conflict resolution - rebase conflicts vs merge\nconflicts.\n* Something like this will likely be introduced as a new rebase option\nin a future release, something like \"--reapply-merges\", or\n\"--rebase-merges-better\", because it will always require the user to\nunderstand that the three-way conflicts presented as part of such an\n\"informed\" merge rebase are subtly different to regular rebase or\nmerge conflicts.\n---\n\nIs it possible to get that sort of simplistic message for this complex topic?\n\nMy apologies if this request is a duplicate - obviously a pointer to\nsome sort of existing summary would be perfect.\n\nThanks,\nTao\n\n[1]: https://lore.kernel.org/git/20220413164336.101390-1-eantoranz@gmail.com/\n[2]: https://lore.kernel.org/git/CABPp-BE=H-OcvGNJKm2zTvV3jEcUV0L=6W76ctpwOewZg56FKg@mail.gmail.com/\n[3]: https://public-inbox.org/git/87r2oxe3o1.fsf@javad.com/\n[4]: https://public-inbox.org/git/a0cc88d2-bfed-ce7b-1b3f-3c447d2b32da@gmail.com/\n[5]: https://github.com/martinvonz/jj\n"},{"id":"453810","messageId":"f87a549f-540e-d0f3-470c-178c2fa141a5@iee.email","threadId":"57750","inReplyTo":"CAPMMpojjs4sjKdN6DAJFSwERdjq9XQgi35CcqkXu7HijadHa1Q@mail.gmail.com","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.email","sentAt":"2022-04-18T14:26:57Z","receivedAt":"2022-04-18T15:22:45Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"A few personal ramblings/comments..\nOn 18/04/2022 12:56, Tao Klerks wrote:\n> Hi folks,\n>\n> The discussion around Edmundo Carmona Antoranz's recent \"git replay\"\n> proposal ([1]) led me down a rabbit-hole reminding me I really don't\n> understand where we stand with rebasing merges, and I don't think I'm\n> alone.\nMy understanding was the 'preserve' may not have retained the expected\nhistory structure. `rebasing` merges is better with the history\nexpectations. Neither address the merge resolutions.\n>\n> I understand the standard advice at the moment to be something like:\n> ---\n> Use a recent git client, use the '--rebase-merges' option (avoid the\n> --preserve-merges option if you find it), and re-resolve any textual\n> and/or semantic conflicts manually (possibly using rerere if you know\n> what you're doing).\n\nThe rerere man page is still magic for me. The UX here could be\nimproved. (also, could the rerere-train be focussed on each merge?)\n> ---\n> Is this correct?\n>\n> This current state/advice seems... suboptimal, at best, because it\n> ignores any information encoded in the original merge commit, as\n> clearly documented in the help. It will often result in you having to\n> resolve conflicts that you already resolved, *where nothing relevant\n> to that merge/commit has changed in your rebase*. If you have rerere,\n> and you know what you are doing, and you were the one that performed\n> the merge, in this repo, then maybe you're ok; similarly if it's a\n> clean merge of course.\n>\n> Elijah Newren describes this problem/opportunity quite carefully in\n> [2], and mentions a bunch of WIP that I have a hard time getting my\n> head around.\n>\n> Similarly, Sergey Organov refers to a thread/discussion four years ago\n> [3], largely involving a debate around two implementations (his and\n> that of Phillip Wood?) that are largely theoretically-equivalent (in a\n> majority of cases), with a lovely explanation of the theory behind the\n> proposal by Igor Djordjevic / Buga [4], but that discussion appears to\n> have dried up; I can't tell whether anything came of it, even if only\n> a manually-usable \"rebase a merge\" script.\n>\n> Finally, Martin von Zweigbergk mentions his git-like VCS [5] which\n> stores conflict data in some kinds of commit as part of a general\n> \"working state is always committable and auto-committed\"\n> state-management strategy; I may be misunderstanding something, but I\n> *think* the resulting conflict-resolution information ends up being\n> reusable in a manner theoretically equivalent to the strategy\n> described by Buga as referenced above.\n>\n> These kinds of discussions frequently seem to feature git experts\n> saying \"I have a script for my version of this problem\" (Elijah,\n> Junio, Johannes Schindelin, ...), or even \"I have a VCS for this\n> problem\" :), but I seem to be too stupid or impatient to dig\n> through/understand whether or when these things will work for a\n> regular joe and how to use them.\n>\n> The temptation, obviously(?), is to write a \"rebase a merge\" script to\n> do something like Sergey Organov's V2 proposal referenced above... but\n> it feels like I'd be spending a bunch of time and ultimately just\n> making things worse for the community, rather than better - helping\n> myself based on my (very limited, but still above average)\n> understanding of merge mechanics, in a way that leaves the general\n> public message / status just as unsatisfactory/unhelpful.\n>\n> Does anyone have an existing simpler answer? Ideally I'm looking for\n> something like:\n\nI believe there is a paper that highlights that even diff's aren't\nunique. So I don't expect merges to be resolvable in the general case.\nIt's why we have software engineers;-) \n\nWe also have to distinguish between interactive and automatic rebase,\nand how much information could be provided to the user about the\nprevious merges (in the insn), and during resolution of a current merge\nconflict compared to the prior conflict. The interactive rebase could\nallow early resolution guidance from the users (e.g. highlighting likely\nsemantic conflicts which shouldn't be auto resolved, which to use\nrerere, etc)\n> ---\n> * When you have a merge in your history, and you are rebasing, follow\n> steps XXXXXX, involving this publicly available gist, or contrib\n> script, or experimental flag, and it will probably do what you want.\n> If there is a (new) conflict when rebasing the merge commit, you can\n> expect conflicts to be presented as YYYYY, because rebasing a merge in\n> this \"informed\" way can fundamentally involve multiple different\n> steps/phases of conflict resolution - rebase conflicts vs merge\n> conflicts.\n> * Something like this will likely be introduced as a new rebase option\n> in a future release, something like \"--reapply-merges\", or\n> \"--rebase-merges-better\", because it will always require the user to\n> understand that the three-way conflicts presented as part of such an\n> \"informed\" merge rebase are subtly different to regular rebase or\n> merge conflicts.\n> ---\n>\n> Is it possible to get that sort of simplistic message for this complex topic?\n>\n> My apologies if this request is a duplicate - obviously a pointer to\n> some sort of existing summary would be perfect.\n>\n> Thanks,\n> Tao\n>\n> [1]: https://lore.kernel.org/git/20220413164336.101390-1-eantoranz@gmail.com/\n> [2]: https://lore.kernel.org/git/CABPp-BE=H-OcvGNJKm2zTvV3jEcUV0L=6W76ctpwOewZg56FKg@mail.gmail.com/\n> [3]: https://public-inbox.org/git/87r2oxe3o1.fsf@javad.com/\n> [4]: https://public-inbox.org/git/a0cc88d2-bfed-ce7b-1b3f-3c447d2b32da@gmail.com/\n> [5]: https://github.com/martinvonz/jj\n(I'm away 3 days, hence early comments)\n--\nPhilip\n"},{"id":"453811","messageId":"xmqqczhe1jgp.fsf@gitster.g","threadId":"57750","inReplyTo":"f87a549f-540e-d0f3-470c-178c2fa141a5@iee.email","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-04-18T15:48:06Z","receivedAt":"2022-04-18T15:55:59Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Philip Oakley <philipoakley@iee.email> writes:\n\n> The rerere man page is still magic for me. The UX here could be\n> improved. (also, could the rerere-train be focussed on each merge?)\n\nI am curious to see a clarification on the question in parentheses.\n\n>> These kinds of discussions frequently seem to feature git experts\n>> saying \"I have a script for my version of this problem\" (Elijah,\n>> Junio, Johannes Schindelin, ...), or even \"I have a VCS for this\n>> problem\" :), but I seem to be too stupid or impatient to dig\n>> through/understand whether or when these things will work for a\n>> regular joe and how to use them.\n\nYou shouldn't take that to mean \"there already is a script to\nsatisfy _my_ needs and no improvement is needed\"; read it as \"we\nhave real need that cannot wait for improvements in this area, so\n(unfortunately) we have built our workflow around some scripts\".\nWe can use these scripts to learn the workflows that are not yet\ndirectly supported with existing tools like rebase, but other than\nthat, their presence is not a sign that discourage you to improve\nthe standard tools---it is quite an opposite.\n"},{"id":"453815","messageId":"ba1ea459-5981-5972-36e6-913eb19c34b4@iee.email","threadId":"57750","inReplyTo":"xmqqczhe1jgp.fsf@gitster.g","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.email","sentAt":"2022-04-18T16:28:35Z","receivedAt":"2022-04-18T16:28:55Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"On 18/04/2022 16:48, Junio C Hamano wrote:\n> Philip Oakley <philipoakley@iee.email> writes:\n>\n>> The rerere man page is still magic for me. The UX here could be\n>> improved. (also, could the rerere-train be focussed on each merge?)\n> I am curious to see a clarification on the question in parentheses.\n>\nIt was the feeling that the rerere-train currently (IIRC) will parse a\nwhole set of commits & merges to create the rerere database and then try\nan apply all the potential resolutions when called upon.\n\nThus for the 'replay' scenario, it could be that the database is\npartitioned and prioritised so that first it applies the resolutions for\nthat particular merge, then considers previous resolutions, and finally\nstarts using resolutions that occur later in the series being rebased.\n\nThere is also the possibility that the rerere database is updated after\neach commit resolution (and especially as merges pass by) so that the\n'prior' resolutions are up to date with any of the current semantic\nchanges, rather than being outdated so could be applied first (i.e. two\nrerere changes being applied to the merge..).\n\nSo, essentially, it's talking a small part of the rerere-train at each\nstep in the replay, so that it's more focussed.\n\nPhilip\n\n(this all assumes my mental model of the rerere magic is roughly correct ;-)\n"},{"id":"453848","messageId":"xmqq35iaz6n3.fsf@gitster.g","threadId":"57750","inReplyTo":"ba1ea459-5981-5972-36e6-913eb19c34b4@iee.email","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-04-18T16:41:04Z","receivedAt":"2022-04-18T16:41:13Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Philip Oakley <philipoakley@iee.email> writes:\n\n> So, essentially, it's talking a small part of the rerere-train at each\n> step in the replay, so that it's more focussed.\n\nAs rerere database is designed to be an O(1) hashtable, having\nknowledge of how many other merge conflicts are to be resolved\nshouldn't affect the time you need to find the relevant record\nto use to help you resulve the conflict you currently see.\n\nThat reminds me of one topic.  I often wondered if it were a mistake\nthat I didn't make the rerere database easily transferrable across\nrepositories (just like \"stash cannot be transport via fetch\" which\nis being worked on recently).  As long as a mergy history that will\nneed to be recreated later gets transferred to a new repository, it\ncan be used to \"train\" the rerere database in the new repository, so\nit probably is a much lower priority.\n\n\"git rerere\" command on the other hand may be in desperate need to\nlearn the \"train\" subcommand to officially support it (and deprecate\nthe \"contrib/rerere-train.sh\").  Especially given that we now can do\nthe necessary \"trial merges\" in core, without touching the working\ntree or the index, thanks to the \"ort\" merge-backend.\n\nThe size of such a project may be appropriate for GSoC (if done the\nsame way as the script, smudging HEAD, index and the working tree),\nor may exceed what is reasonable for GSoC (if done all in-core using\nort machinery).\n\n\n\n"},{"id":"453850","messageId":"87h76qwd8a.fsf@osv.gnss.ru","threadId":"57750","inReplyTo":"CAPMMpojjs4sjKdN6DAJFSwERdjq9XQgi35CcqkXu7HijadHa1Q@mail.gmail.com","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2022-04-18T16:47:01Z","receivedAt":"2022-04-18T16:47:09Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"Tao Klerks <tao@klerks.biz> writes:\n\n> Hi folks,\n>\n> The discussion around Edmundo Carmona Antoranz's recent \"git replay\"\n> proposal ([1]) led me down a rabbit-hole reminding me I really don't\n> understand where we stand with rebasing merges, and I don't think I'm\n> alone.\n\nNeither do I. Status-quo seems to be sub-optimal, or worse. I,\npersonally, still use 2-step merge workflow, see below.\n\n>\n> I understand the standard advice at the moment to be something like:\n> ---\n> Use a recent git client, use the '--rebase-merges' option (avoid the\n> --preserve-merges option if you find it), and re-resolve any textual\n> and/or semantic conflicts manually (possibly using rerere if you know\n> what you're doing).\n> ---\n> Is this correct?\n>\n> This current state/advice seems... suboptimal, at best, because it\n> ignores any information encoded in the original merge commit, as\n> clearly documented in the help. It will often result in you having to\n> resolve conflicts that you already resolved, *where nothing relevant\n> to that merge/commit has changed in your rebase*.\n\nThis is IMHO the least important of 2 drawbacks of this method. The most\nimportant one is that it silently drops user changes, that is major\ndeficiency that, e.g., forces me to split my merges into 2 commits: the\nmerge itself (along with formal conflict resolutions) and the semantic\nfixes to the merge needed by the project. This is constant headache.\n\n[...]\n\nThe above deficiency was the main reason of the:\n\n> Similarly, Sergey Organov refers to a thread/discussion four years ago\n> [3], largely involving a debate around two implementations (his and\n> that of Phillip Wood?) that are largely theoretically-equivalent (in a\n> majority of cases), with a lovely explanation of the theory behind the\n> proposal by Igor Djordjevic / Buga [4], but that discussion appears to\n> have dried up; I can't tell whether anything came of it, even if only\n> a manually-usable \"rebase a merge\" script.\n\nI still hope rebase will finally start to rebase *all* commits, at least\nby default, rather than trying to re-create (some of) them out of thin\nair.\n\nI'd love to implement that myself, but unfortunately it won't happen any\ntime soon, sorry.\n\n> Finally, Martin von Zweigbergk mentions his git-like VCS [5] which\n> stores conflict data in some kinds of commit as part of a general\n> \"working state is always committable and auto-committed\"\n> state-management strategy; I may be misunderstanding something, but I\n> *think* the resulting conflict-resolution information ends up being\n> reusable in a manner theoretically equivalent to the strategy\n> described by Buga as referenced above.\n\nI still think that Git got it right by *not* storing things like that\n(e.g., renaming paths / moving contents), so I'd still propose to\n*rebase* merge *commits* as *content*, without any additional info being\nused, if at all possible. As I wrote in the aforementioned discussion,\nwe should not confuse \"merge-the-process\" and \"merge-the-result\". It's\nthe latter, the commit, that should be rebased no matter what\nparticular process has been used to get to this commit, in accordance\nwith general Git philosophy.\n\nBesides, merge algorithms themselves are subjects to change, so a merge\nperformed 2 years ago might end-up being rather different when attempted\nwith a new algorithm today, rendering information stored from an old\nalgorithm useless.\n\nThat said, I'm not opposed to storing/using additional merge\nmeta-information in general, but it should be an *option* rather than a\nrequirement, to only improve otherwise reliable content rebasing\nalgorithms.\n\nThanks,\n-- Sergey Organov\n"},{"id":"453916","messageId":"CANiSa6ipgk3dRJfOh6i1nL=QqtPTZ6n4ZheT+JowarMTOaeuDg@mail.gmail.com","threadId":"57750","inReplyTo":"CAPMMpojjs4sjKdN6DAJFSwERdjq9XQgi35CcqkXu7HijadHa1Q@mail.gmail.com","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Martin von Zweigbergk","fromEmail":"martinvonz@gmail.com","sentAt":"2022-04-19T04:24:48Z","receivedAt":"2022-04-19T04:25:04Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"On Mon, Apr 18, 2022 at 9:52 AM Tao Klerks <tao@klerks.biz> wrote:\n>\n> Hi folks,\n>\n> The discussion around Edmundo Carmona Antoranz's recent \"git replay\"\n> proposal ([1]) led me down a rabbit-hole reminding me I really don't\n> understand where we stand with rebasing merges, and I don't think I'm\n> alone.\n>\n> I understand the standard advice at the moment to be something like:\n> ---\n> Use a recent git client, use the '--rebase-merges' option (avoid the\n> --preserve-merges option if you find it), and re-resolve any textual\n> and/or semantic conflicts manually (possibly using rerere if you know\n> what you're doing).\n> ---\n> Is this correct?\n>\n> This current state/advice seems... suboptimal, at best, because it\n> ignores any information encoded in the original merge commit, as\n> clearly documented in the help. It will often result in you having to\n> resolve conflicts that you already resolved, *where nothing relevant\n> to that merge/commit has changed in your rebase*. If you have rerere,\n> and you know what you are doing, and you were the one that performed\n> the merge, in this repo, then maybe you're ok; similarly if it's a\n> clean merge of course.\n>\n> Elijah Newren describes this problem/opportunity quite carefully in\n> [2], and mentions a bunch of WIP that I have a hard time getting my\n> head around.\n>\n> Similarly, Sergey Organov refers to a thread/discussion four years ago\n> [3], largely involving a debate around two implementations (his and\n> that of Phillip Wood?) that are largely theoretically-equivalent (in a\n> majority of cases), with a lovely explanation of the theory behind the\n> proposal by Igor Djordjevic / Buga [4], but that discussion appears to\n> have dried up; I can't tell whether anything came of it, even if only\n> a manually-usable \"rebase a merge\" script.\n>\n> Finally, Martin von Zweigbergk mentions his git-like VCS [5] which\n> stores conflict data in some kinds of commit as part of a general\n> \"working state is always committable and auto-committed\"\n> state-management strategy;\n\nJust so there's no misunderstanding, the \"auto-committed working copy\"\nidea is not a requirement for storing conflict objects in trees.\n\n> I may be misunderstanding something, but I\n> *think* the resulting conflict-resolution information ends up being\n> reusable in a manner theoretically equivalent to the strategy\n> described by Buga as referenced above.\n\nI think it's more similar to what Elijah suggested, actually. For\nexample, my VCS lets you rebase a merge commit (the \"evil\" part of it)\neven if you don't rebase all its ancestors. Consider this case:\n\n  X\n /\nA---B---C\n \\       \\\n  D---E---F\n\nIf you now want to rebase E onto X, and then F onto E' and C, then\nElijah's suggestion (and what my VCS does) will work correctly. If I\nunderstood Sergey's proposal, on the other hand, the utility merge\nwould bring in the changes from D as well. Or, put another way, that\nalgorithm is only useful for rebasing \"internal\" merges, where the\nmerge commit is being rebased along with both (all of) its legs\n(again, if I understood it correctly). With the \"rebase changes\ncompared to auto-merged parents\" idea, you can even change the number\nof parents of a commit as you rebase it.\n\n\n>\n> These kinds of discussions frequently seem to feature git experts\n> saying \"I have a script for my version of this problem\" (Elijah,\n> Junio, Johannes Schindelin, ...), or even \"I have a VCS for this\n> problem\" :), but I seem to be too stupid or impatient to dig\n> through/understand whether or when these things will work for a\n> regular joe and how to use them.\n>\n> The temptation, obviously(?), is to write a \"rebase a merge\" script to\n> do something like Sergey Organov's V2 proposal referenced above... but\n> it feels like I'd be spending a bunch of time and ultimately just\n> making things worse for the community, rather than better - helping\n> myself based on my (very limited, but still above average)\n> understanding of merge mechanics, in a way that leaves the general\n> public message / status just as unsatisfactory/unhelpful.\n>\n> Does anyone have an existing simpler answer? Ideally I'm looking for\n> something like:\n> ---\n> * When you have a merge in your history, and you are rebasing, follow\n> steps XXXXXX, involving this publicly available gist, or contrib\n> script, or experimental flag, and it will probably do what you want.\n> If there is a (new) conflict when rebasing the merge commit, you can\n> expect conflicts to be presented as YYYYY, because rebasing a merge in\n> this \"informed\" way can fundamentally involve multiple different\n> steps/phases of conflict resolution - rebase conflicts vs merge\n> conflicts.\n> * Something like this will likely be introduced as a new rebase option\n> in a future release, something like \"--reapply-merges\", or\n> \"--rebase-merges-better\", because it will always require the user to\n> understand that the three-way conflicts presented as part of such an\n> \"informed\" merge rebase are subtly different to regular rebase or\n> merge conflicts.\n> ---\n>\n> Is it possible to get that sort of simplistic message for this complex topic?\n>\n> My apologies if this request is a duplicate - obviously a pointer to\n> some sort of existing summary would be perfect.\n>\n> Thanks,\n> Tao\n>\n> [1]: https://lore.kernel.org/git/20220413164336.101390-1-eantoranz@gmail.com/\n> [2]: https://lore.kernel.org/git/CABPp-BE=H-OcvGNJKm2zTvV3jEcUV0L=6W76ctpwOewZg56FKg@mail.gmail.com/\n> [3]: https://public-inbox.org/git/87r2oxe3o1.fsf@javad.com/\n> [4]: https://public-inbox.org/git/a0cc88d2-bfed-ce7b-1b3f-3c447d2b32da@gmail.com/\n> [5]: https://github.com/martinvonz/jj\n"},{"id":"453921","messageId":"CAPMMpog-=m2e9mgFMvUhHKLPPboqP1gkg5GkHJF2tswjp+P-1g@mail.gmail.com","threadId":"57750","inReplyTo":"CANiSa6ipgk3dRJfOh6i1nL=QqtPTZ6n4ZheT+JowarMTOaeuDg@mail.gmail.com","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Tao Klerks","fromEmail":"tao@klerks.biz","sentAt":"2022-04-19T09:49:53Z","receivedAt":"2022-04-19T09:50:12Z","isPatch":false,"sender":{"key":"tao@klerks.biz","avatar":"https://avatars.githubusercontent.com/u/531704?v=4"},"body":"On Tue, Apr 19, 2022 at 6:25 AM Martin von Zweigbergk\n<martinvonz@gmail.com> wrote:\n>\n> Consider this case:\n>\n>   X\n>  /\n> A---B---C\n>  \\       \\\n>   D---E---F\n>\n> If you now want to rebase E onto X, and then F onto E' and C, then\n> Elijah's suggestion (and what my VCS does) will work correctly. If I\n> understood Sergey's proposal, on the other hand, the utility merge\n> would bring in the changes from D as well. Or, put another way, that\n> algorithm is only useful for rebasing \"internal\" merges, where the\n> merge commit is being rebased along with both (all of) its legs\n> (again, if I understood it correctly).\n>\n\nFWIW, I don't believe this to be the case. If you rebase E onto X, the\nway the \"D side\" of the merge will be resolved, on X, will be as a\ncombination of \"Addition of X\" and \"Removal of D\" onto the previous E\ncommit state. The secret sauce in Sergey's approach is the application\nof a patch representing the \"inverted change\" to the \"D arm\" of the\nmerge base in the original merge vs the \"new D arm\" (which  happens to\nno longer contain D and have X instead - I just have no better way to\nrefer to it).\n\nI haven't understood or explored Elijah's suggestion (or your\nimplementation), but based on your description, it sounds like they\nend up being equivalent in result, but maybe present any conflicts\ndifferently (as a different patch applying to a different base). I\nexpect cleanly rebased merges to come out the same, and the same\nsituations/scenarios to lead to clean merges vs conflicts, but the\npresentation of conflicts to likely look different.\n\nThat said, I haven't tested them both, I was just hoping for a\n\"current state of existing merge information reuse for merge-rebasing\nusers\" summary, and it doesn't look like there's one available so far.\n"},{"id":"453930","messageId":"CANiSa6i7iyVB4uoy1fF4EmorGFoDgYsf1zEO6F6UPeBSkSfjJA@mail.gmail.com","threadId":"57750","inReplyTo":"CAPMMpog-=m2e9mgFMvUhHKLPPboqP1gkg5GkHJF2tswjp+P-1g@mail.gmail.com","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Martin von Zweigbergk","fromEmail":"martinvonz@gmail.com","sentAt":"2022-04-19T15:10:59Z","receivedAt":"2022-04-19T15:11:17Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"On Tue, Apr 19, 2022 at 2:50 AM Tao Klerks <tao@klerks.biz> wrote:\n>\n> On Tue, Apr 19, 2022 at 6:25 AM Martin von Zweigbergk\n> <martinvonz@gmail.com> wrote:\n> >\n> > Consider this case:\n> >\n> >   X\n> >  /\n> > A---B---C\n> >  \\       \\\n> >   D---E---F\n> >\n> > If you now want to rebase E onto X, and then F onto E' and C, then\n> > Elijah's suggestion (and what my VCS does) will work correctly. If I\n> > understood Sergey's proposal, on the other hand, the utility merge\n> > would bring in the changes from D as well. Or, put another way, that\n> > algorithm is only useful for rebasing \"internal\" merges, where the\n> > merge commit is being rebased along with both (all of) its legs\n> > (again, if I understood it correctly).\n> >\n>\n> FWIW, I don't believe this to be the case. If you rebase E onto X, the\n> way the \"D side\" of the merge will be resolved, on X, will be as a\n> combination of \"Addition of X\" and \"Removal of D\" onto the previous E\n> commit state. The secret sauce in Sergey's approach is the application\n> of a patch representing the \"inverted change\" to the \"D arm\" of the\n> merge base in the original merge vs the \"new D arm\" (which  happens to\n> no longer contain D and have X instead - I just have no better way to\n> refer to it).\n\nI see, it applies a reversed D onto E before creating the utility\nmerges. That makes sense.\n\n> I haven't understood or explored Elijah's suggestion (or your\n> implementation), but based on your description, it sounds like they\n> end up being equivalent in result, but maybe present any conflicts\n> differently (as a different patch applying to a different base). I\n> expect cleanly rebased merges to come out the same, and the same\n> situations/scenarios to lead to clean merges vs conflicts, but the\n> presentation of conflicts to likely look different.\n\nYes, pretty much. I expect there would be some minor differences but I\ncan't think of an example.\n"},{"id":"453931","messageId":"CANiSa6jAjbPRii8GYYLzU88K9P-TG5GGBJGY-H1CwmPkb+yU-w@mail.gmail.com","threadId":"57750","inReplyTo":"87h76qwd8a.fsf@osv.gnss.ru","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Martin von Zweigbergk","fromEmail":"martinvonz@gmail.com","sentAt":"2022-04-19T15:24:21Z","receivedAt":"2022-04-19T15:25:38Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"On Tue, Apr 19, 2022 at 5:25 AM Sergey Organov <sorganov@gmail.com> wrote:\n>\n> Tao Klerks <tao@klerks.biz> writes:\n>\n> > Finally, Martin von Zweigbergk mentions his git-like VCS [5] which\n> > stores conflict data in some kinds of commit as part of a general\n> > \"working state is always committable and auto-committed\"\n> > state-management strategy; I may be misunderstanding something, but I\n> > *think* the resulting conflict-resolution information ends up being\n> > reusable in a manner theoretically equivalent to the strategy\n> > described by Buga as referenced above.\n>\n> I still think that Git got it right by *not* storing things like that\n> (e.g., renaming paths / moving contents),\n\nMy VCS doesn't store that either. Maybe you're thinking of Darcs or\nPijul? [1] explains what my VCS stores. FYI, [2] explains other\nbenefits of first-class conflicts; being able to rebase merge commits\nis much less important than the other benefits, IMO (but it's still\nimportant).\n\n> so I'd still propose to\n> *rebase* merge *commits* as *content*, without any additional info being\n> used, if at all possible.\n\nRebasing is about applying changes from some commit onto some other\ncommit, as I'm sure you know. What Elijah and I are proposing is to\nconsider the changes in the commit to be relative to the auto-merged\nparents (regardless of the number of parents - auto-merging a single\nparent commit just yields that commit), although I don't think Elijah\nphrased it that way.\n\n> As I wrote in the aforementioned discussion,\n> we should not confuse \"merge-the-process\" and \"merge-the-result\". It's\n> the latter, the commit, that should be rebased no matter what\n> particular process has been used to get to this commit, in accordance\n> with general Git philosophy.\n>\n> Besides, merge algorithms themselves are subjects to change, so a merge\n> performed 2 years ago might end-up being rather different when attempted\n> with a new algorithm today, rendering information stored from an old\n> algorithm useless.\n\nI agree with all of that.\n\n[1] https://github.com/martinvonz/jj/blob/main/docs/technical/conflicts.md\n[2] https://github.com/martinvonz/jj/blob/main/docs/conflicts.md\n"},{"id":"453932","messageId":"CANiSa6hEJMWPyfZ_KqgHcKXhMdT7doTnxkK7GZzf-QBh6DhATg@mail.gmail.com","threadId":"57750","inReplyTo":"xmqq35iaz6n3.fsf@gitster.g","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Martin von Zweigbergk","fromEmail":"martinvonz@gmail.com","sentAt":"2022-04-19T15:32:23Z","receivedAt":"2022-04-19T15:32:39Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"On Tue, Apr 19, 2022 at 6:57 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Philip Oakley <philipoakley@iee.email> writes:\n>\n> > So, essentially, it's talking a small part of the rerere-train at each\n> > step in the replay, so that it's more focussed.\n>\n> That reminds me of one topic.\n\nAnd it reminds me of a discussion about first-class conflicts vs\nrerere I had recently [1] (Philip's email hasn't been delivered to me\nyet). As I wrote there, I think most of rerere's use cases can be\nfulfilled by first-class conflicts. I understand that it would be a\nhuge project (much more than appropriate for GSoC :)) to add such\nsupport to Git. I just want to make sure the project is aware of the\nidea.\n\n[1] https://github.com/martinvonz/jj/issues/175#issuecomment-1079831788\n"},{"id":"453936","messageId":"87zgkh9buq.fsf@osv.gnss.ru","threadId":"57750","inReplyTo":"CANiSa6jAjbPRii8GYYLzU88K9P-TG5GGBJGY-H1CwmPkb+yU-w@mail.gmail.com","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Sergey Organov","fromEmail":"sorganov@gmail.com","sentAt":"2022-04-19T18:17:33Z","receivedAt":"2022-04-19T18:23:17Z","isPatch":false,"sender":{"key":"sorganov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8501568?v=4"},"body":"Martin von Zweigbergk <martinvonz@gmail.com> writes:\n\n> On Tue, Apr 19, 2022 at 5:25 AM Sergey Organov <sorganov@gmail.com> wrote:\n>>\n\n[...]\n\n>> so I'd still propose to\n>> *rebase* merge *commits* as *content*, without any additional info being\n>> used, if at all possible.\n>\n> Rebasing is about applying changes from some commit onto some other\n> commit, as I'm sure you know.\n\nYep.\n\n> What Elijah and I are proposing is to\n> consider the changes in the commit to be relative to the auto-merged\n> parents (regardless of the number of parents - auto-merging a single\n> parent commit just yields that commit), although I don't think Elijah\n> phrased it that way.\n\nI admit I didn't put enough thought into this new (to me) idea, but I\ncan't immediately see advantages of this method. Suppose, for the sake\nof the argument, that the merge commit in question has been created\nwithout any use of an auto-merge (whatever it actually means) in the\nfirst place. What's then the reason to consider it to be a diff with\nrespect to an auto-merge? What advantages would it bring?\n\nThen, do we need to be able to reproduce that exact auto-merge in 2\nyears from now for the method to work reliably? If so, isn't it a\nproblem, as we seem to agree that merge algorithms are subject to change\nover time?\n\nEssentially, this method apparently still puts a result of particular\nprocedure at the root of the method, again mixing merge-a-process with\nmerge-commit-the-result, that to me looks fundamentally flawed. I still\nthink that at its core Git should remain indifferent to the way a commit\nhas been created, be it merge or non-merge.\n\nOTOH, the method of rebasing merge commits I've described long ago has\nno assumptions about procedures involved in creation of the commit to be\nrebased, nor does it need any notion of conflicts being involved in the\nprocess, if any. It simply doesn't care, exactly the same way current\nrebase doesn't care, when it rebases non-merge commits, if they were\ncreated, say, using conflicting cherry-picks. What it cares about is\npreserving the content by properly applying the recorded changes to the\nnew base. This property of the method I've suggested makes me believe it\nis the best candidate for the core functionality, on top of which other\nusable features could evolve.\n\nAnyway, the choice is up to whoever gets time and desire to implement\nit, and, not being that guy for now, I'm only looking forward for any\nsuitable solution for reliable rebasing of merge commits.\n\nThanks,\n-- Sergey Organov\n"},{"id":"453951","messageId":"xmqqsfq8s41v.fsf@gitster.g","threadId":"57750","inReplyTo":"CANiSa6hEJMWPyfZ_KqgHcKXhMdT7doTnxkK7GZzf-QBh6DhATg@mail.gmail.com","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-04-20T05:43:24Z","receivedAt":"2022-04-20T05:43:31Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Martin von Zweigbergk <martinvonz@gmail.com> writes:\n\n> On Tue, Apr 19, 2022 at 6:57 AM Junio C Hamano <gitster@pobox.com> wrote:\n>>\n>> Philip Oakley <philipoakley@iee.email> writes:\n>>\n>> > So, essentially, it's talking a small part of the rerere-train at each\n>> > step in the replay, so that it's more focussed.\n>>\n>> That reminds me of one topic.\n>\n> And it reminds me of a discussion about first-class conflicts vs\n> rerere I had recently [1] (Philip's email hasn't been delivered to me\n> yet). As I wrote there, I think most of rerere's use cases can be\n> fulfilled by first-class conflicts. I understand that it would be a\n> huge project (much more than appropriate for GSoC :)) to add such\n> support to Git. I just want to make sure the project is aware of the\n> idea.\n>\n> [1] https://github.com/martinvonz/jj/issues/175#issuecomment-1079831788\n\nI saw that before, but neither of these two \"use cases\" solve a\nproblem relevant to what I have to do often.  It may be a case where\nyou have a hammer while rerere is a screwdriver, perhaps?  Each is\nuseful in its own ways and is good at different applications.\n\nRebuilding of 'seen' multiple times every day may superficially be\nsimilar to \"test merge\" case you mention there, but the desired end\nresult from keeping multiple topics in master..seen chain, and have\nselected ones (not necessarily in the order in 'master..seen')\ngraduate while keeping others and rebuilding 'seen' with them never\ninvolves artificially linearlized history in the end, and that is an\nexplicit goal---to avoid the last-minute rebasing to the upstream,\nwhich can introduce unnecessary bugs.\n\nWhen I merge topics from 'seen' to 'next', I first reorder the\ntopics so that these topics that are planned to be merged to 'next'\ncome directly on top of the tree that matches 'next' in the\n'master..seen' chain, so that the exact state planned to be in\n'next' in the next iteration appears in 'seen' and be tested.  The\nmerge of these topics to 'next' happens in the next integration\niteration after this preparatory step passes.  It is the same way\nwhen topics that have been cooking in 'next' are (first planned to\nand then actually) merged to 'master'.  There is no \"final last\nminute\" rebase involved.\n\nAnother thing that I didn't quite see in your \"I see rebase as\nreplaying the change between parent and child\" is how different\norder of merging is handled.  It often happens that topic A and\ntopic B have funny interactions, and the resolution rerere records\nwhen I first merge topic A to 'seen' and then topic B (at which time\nthe conflict we are interested in happens) is later cleanly reused\nif topic B turns out to go first long before topic C graduates.\nWhen such a reordering happens, topic B will be merged first\n(without causing the conflict between topics A and B), then topic A\nis merged.  Dealing with such a reordering of topics was an explicit\ngoal of 'rerere' and it works reasonably well, but it is no clear\nhow [1] you cited above handles such a use case.\n\nThe most importantly, at the philosophical level, in order to allow\nearlier mistakes to be corrected later, Git tries to avoid casting\nheuristic decisions in immutable objects when possible.\n\nNot recording \"in this commit, parent and child trees rename path A\nto B, combine some contents of path C and D to create a new path E\"\nand instead computing renames when we actually compare these two\ntrees, is an example of the application of the philosophy.  It\nallows rename detection heuristics at the runtime to improve over\ntime and a commit you made 5 years ago will be shown better with the\nimproved rename detection logic.  We do avoid recomputing the same\ninformation over and over again by having long lived cache data\nstructure like commit-graph, but they are left out of the central\ndata structure and can be reproducible.\n\nKeeping the rerere database outside the commit object is another\napplication of the same philosophy.  There needs a clear way to nuke\nan earlier recorded resolution that was faulty without having to\nrewrite the history, and having it outside the commit object is a\nmust, and having database in .git/rr-cache/ is one possible\nimplementation to achieve that goal.\n\nThanks.\n"},{"id":"454042","messageId":"CANiSa6iuFkyuc3DfQcSnmXdbHOXgc2HTp3SE9Segd=pV8WVV4Q@mail.gmail.com","threadId":"57750","inReplyTo":"xmqqsfq8s41v.fsf@gitster.g","subject":"Re: Current state / standard advice for rebasing merges without information loss/re-entry?","fromName":"Martin von Zweigbergk","fromEmail":"martinvonz@gmail.com","sentAt":"2022-04-20T23:54:36Z","receivedAt":"2022-04-20T23:54:52Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"On Tue, Apr 19, 2022 at 10:43 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Martin von Zweigbergk <martinvonz@gmail.com> writes:\n>\n> > On Tue, Apr 19, 2022 at 6:57 AM Junio C Hamano <gitster@pobox.com> wrote:\n> >>\n> >> Philip Oakley <philipoakley@iee.email> writes:\n> >>\n> >> > So, essentially, it's talking a small part of the rerere-train at each\n> >> > step in the replay, so that it's more focussed.\n> >>\n> >> That reminds me of one topic.\n> >\n> > And it reminds me of a discussion about first-class conflicts vs\n> > rerere I had recently [1] (Philip's email hasn't been delivered to me\n> > yet). As I wrote there, I think most of rerere's use cases can be\n> > fulfilled by first-class conflicts. I understand that it would be a\n> > huge project (much more than appropriate for GSoC :)) to add such\n> > support to Git. I just want to make sure the project is aware of the\n> > idea.\n> >\n> > [1] https://github.com/martinvonz/jj/issues/175#issuecomment-1079831788\n>\n> I saw that before, but neither of these two \"use cases\" solve a\n> problem relevant to what I have to do often.  It may be a case where\n> you have a hammer while rerere is a screwdriver, perhaps?  Each is\n> useful in its own ways and is good at different applications.\n\nYes, that's probably true. I understand that there are scenarios that\nrerere helps with that first-class conflicts (at least the way I\nimplemented them) do not.\n\n> Rebuilding of 'seen' multiple times every day may superficially be\n> similar to \"test merge\" case you mention there, but the desired end\n> result from keeping multiple topics in master..seen chain, and have\n> selected ones (not necessarily in the order in 'master..seen')\n> graduate while keeping others and rebuilding 'seen' with them never\n> involves artificially linearlized history in the end, and that is an\n> explicit goal---to avoid the last-minute rebasing to the upstream,\n> which can introduce unnecessary bugs.\n>\n> When I merge topics from 'seen' to 'next', I first reorder the\n> topics so that these topics that are planned to be merged to 'next'\n> come directly on top of the tree that matches 'next' in the\n> 'master..seen' chain, so that the exact state planned to be in\n> 'next' in the next iteration appears in 'seen' and be tested.  The\n> merge of these topics to 'next' happens in the next integration\n> iteration after this preparatory step passes.  It is the same way\n> when topics that have been cooking in 'next' are (first planned to\n> and then actually) merged to 'master'.  There is no \"final last\n> minute\" rebase involved.\n\nThanks for explaining it in such detail. I'm afraid I still don't\nunderstand how it's related to first-class conflicts vs rerere (I've\nread the text at least 5 times).\n\n> Another thing that I didn't quite see in your \"I see rebase as\n> replaying the change between parent and child\" is how different\n> order of merging is handled.  It often happens that topic A and\n> topic B have funny interactions, and the resolution rerere records\n> when I first merge topic A to 'seen' and then topic B (at which time\n> the conflict we are interested in happens) is later cleanly reused\n> if topic B turns out to go first long before topic C graduates.\n> When such a reordering happens, topic B will be merged first\n> (without causing the conflict between topics A and B), then topic A\n> is merged.  Dealing with such a reordering of topics was an explicit\n> goal of 'rerere' and it works reasonably well, but it is no clear\n> how [1] you cited above handles such a use case.\n\nGood point! That's not a use case I had considered. To make sure I\nunderstand you correctly, the reordering you're talking about is\nsomething like the difference between the following two graphs\n(children on top, not on the right).\n\n  N\n  |\\\n  M |\n /| |\nX Y Z\n\n  P\n /|\n| O\n| |\\\nX Y Z\n\nThe problem (for my tool) here is that commit N contains resolutions\nfor conflicts between X and Z *and* between Y and Z, so when the\nmerges are done in the opposite order, you'll want to put some of the\nconflict resolutions from M in O and some in P. There are commands for\nmoving changes (including conflict resolutions) between commits, so\nyou could use that here, but rerere is way smoother since it's\nautomatic.\n\n> The most importantly, at the philosophical level, in order to allow\n> earlier mistakes to be corrected later, Git tries to avoid casting\n> heuristic decisions in immutable objects when possible.\n>\n> Not recording \"in this commit, parent and child trees rename path A\n> to B, combine some contents of path C and D to create a new path E\"\n> and instead computing renames when we actually compare these two\n> trees, is an example of the application of the philosophy.  It\n> allows rename detection heuristics at the runtime to improve over\n> time and a commit you made 5 years ago will be shown better with the\n> improved rename detection logic.  We do avoid recomputing the same\n> information over and over again by having long lived cache data\n> structure like commit-graph, but they are left out of the central\n> data structure and can be reproducible.\n>\n> Keeping the rerere database outside the commit object is another\n> application of the same philosophy.  There needs a clear way to nuke\n> an earlier recorded resolution that was faulty without having to\n> rewrite the history, and having it outside the commit object is a\n> must, and having database in .git/rr-cache/ is one possible\n> implementation to achieve that goal.\n\nI agree with all of that. I guess there's some implication about\nfirst-class conflicts vs rerere here too? Is the concern that if you\nleave some conflict unresolved for years, it might be that the tool\nnow could have actually resolved that conflict instead of marking it\nas a conflict in a file? So by not being forced to redo the merge, you\nare instead trying to resolve an auto-resolvable conflict. Yes, that\nis a problem, but it seems very small. I'm probably missing a more\nserious problem.\n"}]}