{"thread":{"id":"45282","subject":"rebase: confusing behaviour since --fork-point","startedAt":"2017-03-03T16:37:58Z","lastAt":"2017-03-03T16:37:58Z","messageCount":1,"participants":["Laszlo Kiss"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"313193","messageId":"CAO0LFki4PN8zz2xpoSpjTHJGS=NG_suQYR27EcmzEMiaCw9kuA@mail.gmail.com","threadId":"45282","inReplyTo":null,"subject":"rebase: confusing behaviour since --fork-point","fromName":"Laszlo Kiss","fromEmail":"kisslas.git@gmail.com","sentAt":"2017-03-03T16:37:28Z","receivedAt":"2017-03-03T16:37:58Z","isPatch":false,"sender":{"key":"kisslas.git@gmail.com","avatar":null},"body":"Hi all,\n\nThis will be a bit long, sorry in advance.\n\nI've hit a problem with how rebase works since the introduction of the\n--fork-point option. I initially thought it was a bug until the kind\nfolks over at git-for-windows patiently told me otherwise.\n\nConsider the following:\n\n-------8<-------\n# On branch master which is at origin/master\n# hack hack hack\n\ngit commit -am'First topic commit'\n# optionally followed by more commits\n\n# realize I want all this on a different branch instead\n# (maybe I just forgot to create one; would be typical)\n\ngit checkout -b topic --track\ngit branch -f master origin/master\n\n# optionally add more commits to 'topic' and/or update 'master'\n# with changes to 'origin/master', then finally:\n\ngit rebase    # or git pull --rebase\n------->8-------\n\nWhat happens is that 'First topic commit' is discarded because rebase,\nwith this syntax, defaults to --fork-point, which then works out from\nmaster's reflog that the commit in question was previously part of the\nupstream branch. The rebase is then carried out under the assumption\nthat, even though that specific commit is no longer in master,\nsomething equivalent to it or superseding it is, or else it is meant to\nbe dropped - which would likely be the case if a complicated history\nrewrite happened, but is not the case here.\n\nThere are two reasons why I think this is confusing and should be\nchanged:\n\n(1) My mental model of git after some 5 years of using it is such that\n    I view the reflog as auxiliary information for purposes of mining\n    history or recovering from mistakes, and I rely only on the\n    contents and parent-child relationships of commits to work out what\n    a command I'm about to run will do. I would expect the vast\n    majority of users to have a similar mental model, in which case the\n    fact that the same commits can be rebased differently depending on\n    the data in the reflog will be equally confusing to those users.\n\n(2) Most people don't like to rebase too often, consequently the time\n    elapsed from a user creating the topic branch and resetting its\n    upstream until actually rebasing it can be days or weeks, by the\n    end of which they are unlikely to remember the circumstances of\n    creating the branch. Even more alarmingly, they may have committed\n    dozens of further changes, and therefore may not even notice that\n    the first few of those silently disappeared. (I'm not making this\n    up: see discussion links below in PS.)\n\nI believe the correct design would be to always make --no-fork-point\nthe default for rebase, and only use --fork-point when explicitly\nspecified. This would potentially be inconvenient for those who rebase\non top of complicated history rewrites, but said inconvenience would be\nmitigated by several factors:\n- Anyone doing rebases like that will already know that they can go\n  wrong in a million ways.\n- Perhaps more crucially, they will have a way of noticing if it went\n  wrong, with all relevant information in short-term memory, so would\n  recover easily.\n- If the rebase turns out to be really complex, they are likely to\n  resort to rebase -i, which shows full details of what is about to\n  happen, moreover it seems relatively simple to enhance the contents\n  of the rebase-todo file so that full information about the merge-base\n  and fork-point is readily available.\n\nIf changing the default is not an option, e.g. because of backwards\ncompatibility concerns, then some configurability could still be\nhelpful, e.g. rebase.useForkPoint = never / auto / always (default\nauto, to keep the current behaviour). Although I suspect this would\njust lead to everyone suggesting setting this to 'never'. In any case\nthis would provide a way to ensure that any git newbies in my\norganization don't spend days trying to figure this out like I've just\ndone.\n\nAssuming there is agreement to do one of the above (I don't even know\nwhose agreement is required), what's the process for getting it\nimplemented? Sorry, that probably counts as a dumb question, but I've\nnever been around open-source projects much & need someone to show me\nthe ropes.\n\nMany thanks\nLaszlo\n\nPS. Further reading about the same topic if anyone is interested:\n- http://marc.info/?l=git&m=140991293402880&w=2 (from this same mailing\n  list 2+ years ago, but I can see no clear conclusion)\n- https://github.com/git-for-windows/git/issues/1076 (my bug report\n  where contacting this list was suggested)\n- http://stackoverflow.com/questions/22790765 and\n  http://stackoverflow.com/questions/35320740 (various SO users being\n  confused and asking about / discussing the same thing)\n"}]}