{"thread":{"id":"59371","subject":"[RFC PATCH] hooks--pre-push.sample: identify branch point","startedAt":"2023-03-09T22:10:35Z","lastAt":"2023-03-16T17:33:15Z","messageCount":6,"participants":["Antoine Beaupré","Felipe Contreras"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"473320","messageId":"20230309220405.219212-1-anarcat@debian.org","threadId":"59371","inReplyTo":null,"subject":"[RFC PATCH] hooks--pre-push.sample: identify branch point","fromName":"Antoine Beaupré","fromEmail":"anarcat@debian.org","sentAt":"2023-03-09T22:04:05Z","receivedAt":"2023-03-09T22:10:35Z","isPatch":true,"sender":{"key":"anarcat@debian.org","avatar":"https://avatars.githubusercontent.com/u/796623?v=4"},"body":"The pre-push hook introduced in 87c86dd14a (Add sample pre-push hook\nscript, 2013-01-13) has a pretty naive implementation that inspects\nthe entirety of that branch history, regardless of previous merges.\n\nIn other words, if you create a topic branch from a current history,\nthe entire history will be inspected by the pre-push hook. In my case,\nthere was an old \"WIP\" commit log that broke the hook, even though\nthat commit wasn't specific to the branch in question, nor was it\nintroduced by the push.\n\nThis patch aims at fixing that problem by restricting the revisions inspected when a new branch is pushed to something that is more specific to that branch.\n\nThis implementation will first attempt to find an ancestor that the\ncurrent branch is related to (`--merged=`). This is where this\nimplementation is the most questionable; normally you would put\n`master` or `main` as a base branch, but who knows what people\nactually use for this nowadays. And besides, it's fair to assume you\ncould be pushing something based on a branch that already exists\nupstream that is *not* master or main... But still, that's a tricky\nbit I'm not sure of.\n\nThen we find the \"branch point\" which is the latest commit on the\nancestor branch that's shared with the inspected ref. This,\ninterestingly, seems to be a really tricky problem as well. I base my\nimplementation off this answer on Stack Overflow (I know! at least\nit's not ChatGPT!):\n\nhttps://stackoverflow.com/a/71193866/1174784\n\nThere are currently a whopping twenty-five answers to that question in\nthat thread, and I'm hoping the community here will have a more\ndefinitive answer to this question. I have picked the answer that uses\nthe least possible external commands, but it still uses a `tail -1`\nwhich I'm somewhat unhappy about. I have thought of using\n`--max-count` for this instead, but I understand that probably does\nthe equivalent of a `head -n` *and* it's applied before `--reverse`,\nso there's not other way to do this.\n\nThe final question to answer here is whether this is a good idea in\nthe first place, and whether this is the right place to answer this\nkind of question. I happen to really like using pre-push (instead of\npre-commit) for inspecting my work before submitting it upstream, so\nit was a natural fit for me, but this might be everyone's taste.\n\nAs the subject indicates, I would very much welcome comments on\nthis. I would be happy to submit a more elaborate version of\nthis (e.g. with unit tests) if it's interesting for the community, or\nreceive guidance on where best this could be implemented or improved.\n\nSigned-off-by: Antoine Beaupré <anarcat@debian.org>\n---\n templates/hooks--pre-push.sample | 20 ++++++++++++++++++--\n 1 file changed, 18 insertions(+), 2 deletions(-)\n\ndiff --git a/templates/hooks--pre-push.sample b/templates/hooks--pre-push.sample\nindex 4ce688d32b..f871b65195 100755\n--- a/templates/hooks--pre-push.sample\n+++ b/templates/hooks--pre-push.sample\n@@ -33,8 +33,24 @@ do\n \telse\n \t\tif test \"$remote_oid\" = \"$zero\"\n \t\tthen\n-\t\t\t# New branch, examine all commits\n-\t\t\trange=\"$local_oid\"\n+\t\t\t# new branch\n+\t\t\t#\n+\t\t\t# search for a base branch that's part of this branch, latest modified\n+\t\t\t#\n+\t\t\t# it's a better heuristic than hardcoding \"master\" or \"main\"\n+\t\t\tbase_branch=$(git for-each-ref \\\n+\t\t\t\t\t  --merged=\"$local_ref\" \\\n+\t\t\t\t\t  --no-contains=\"$local_ref\" \\\n+\t\t\t\t\t  --format=\"%(refname:strip=-1)\" \\\n+\t\t\t\t\t  --sort='-*authordate' \\\n+\t\t\t\t\t  refs/heads )\n+\t\t\t# find the place where we branched off the base branch\n+\t\t\tbranch_point=$(git rev-parse \\\n+\t\t\t\t\t   $(git rev-list --exclude-first-parent-only \\\n+\t\t\t\t\t\t ^\"$base_branch\" \"$local_ref\"| tail -1)^ \\\n+                                    )\n+\t\t\t# examine all commits up to the branch point\n+\t\t        range=\"$branch_point..$local_oid\"\n \t\telse\n \t\t\t# Update to existing branch, examine new commits\n \t\t\trange=\"$remote_oid..$local_oid\"\n-- \n2.39.2\n\n"},{"id":"473328","messageId":"CAMP44s2=qzmF1Odc_auCaKQmTBYD53YYtaJv_LGwvoFDmTxPSA@mail.gmail.com","threadId":"59371","inReplyTo":"20230309220405.219212-1-anarcat@debian.org","subject":"Re: [RFC PATCH] hooks--pre-push.sample: identify branch point","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2023-03-09T23:22:55Z","receivedAt":"2023-03-09T23:23:16Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Hi Antoine,\n\nOn Thu, Mar 9, 2023 at 4:34 PM Antoine Beaupré <anarcat@debian.org> wrote:\n\n> https://stackoverflow.com/a/71193866/1174784\n>\n> There are currently a whopping twenty-five answers to that question in\n> that thread, and I'm hoping the community here will have a more\n> definitive answer to this question. I have picked the answer that uses\n> the least possible external commands, but it still uses a `tail -1`\n> which I'm somewhat unhappy about. I have thought of using\n> `--max-count` for this instead, but I understand that probably does\n> the equivalent of a `head -n` *and* it's applied before `--reverse`,\n> so there's not other way to do this.\n\nI spent an inordinate amount of time trying to answer that question a\ndecade ago, and my conclusion after trying every possible combination\nis that it's simply not possible. Every solution at the end of the day\nwill be a hack that can be broken with a corner case. It has already\nbeen discussed in this mailing list [1], and nobody found a solution.\n\nThat's why I wrote a patch to implement a branch@{tail} helper to show\nan auxiliary ref to the beginning of the branch. I don't think I ever\nsent it to the mailing list, as my patches are rarely merged, but I'm\nsure I have it somewhere.\n\nThe other solution I thought of was adding an update-branch hook that\ncould be run every time a branch is updated, and then the hook would\nupdate the branch tail reference [2]. As expected, that patch wasn't\nmerged either.\n\nIt's interesting how we keep coming back to the same problems; right\nnow there's a discussion in the git-users mailing list precisely about\nthe same topic: how to find the branch point, in particular so `git\nname-rev` shows the correct branch a commit belongs to (which is\notherwise just a bad guess).\n\nFWIW my motivation at the time was to prove Mercurial users wrong\nregarding features that they have and Git doesn't, I contended that\nMercurial named branches (aka commit labels) were not necessary, and\neverything they achieved could be achieved in Git through different\nmeans. That turned out to be untrue, as there is one thing Mercurial\ncan do that Git can't: show the precise point a branch started from.\n\nI abandoned my efforts back then, but the topic seems inescapable, as\nthat is also needed by new tools like `git range-diff`, so in my own\ntool to keep track of patch series (`git send-series`[2])I end up\ncreating a ton of refs just to properly keep track of the branch\npoints of my different patch series.\n\nIf only Git developers acknowledged the current very real limitation,\nsomething could be done about it.\n\nCheers.\n\n[1] https://lore.kernel.org/git/CAMP44s0f7AJPQSTDgvy0U7vx8nxzq2a3vMhSr2Tcc61fetFkJA@mail.gmail.com/\n[2] https://lore.kernel.org/git/1398047016-21643-1-git-send-email-felipe.contreras@gmail.com/\n[3] https://github.com/felipec/git-send-series\n\n-- \nFelipe Contreras\n"},{"id":"473359","messageId":"87356ctvta.fsf@angela.anarc.at","threadId":"59371","inReplyTo":"CAMP44s2=qzmF1Odc_auCaKQmTBYD53YYtaJv_LGwvoFDmTxPSA@mail.gmail.com","subject":"Re: [RFC PATCH] hooks--pre-push.sample: identify branch point","fromName":"Antoine Beaupré","fromEmail":"anarcat@debian.org","sentAt":"2023-03-10T16:28:33Z","receivedAt":"2023-03-10T16:49:11Z","isPatch":true,"sender":{"key":"anarcat@debian.org","avatar":"https://avatars.githubusercontent.com/u/796623?v=4"},"body":"On 2023-03-09 17:22:55, Felipe Contreras wrote:\n> Hi Antoine,\n>\n> On Thu, Mar 9, 2023 at 4:34 PM Antoine Beaupré <anarcat@debian.org> wrote:\n>\n>> https://stackoverflow.com/a/71193866/1174784\n>>\n>> There are currently a whopping twenty-five answers to that question in\n>> that thread, and I'm hoping the community here will have a more\n>> definitive answer to this question. I have picked the answer that uses\n>> the least possible external commands, but it still uses a `tail -1`\n>> which I'm somewhat unhappy about. I have thought of using\n>> `--max-count` for this instead, but I understand that probably does\n>> the equivalent of a `head -n` *and* it's applied before `--reverse`,\n>> so there's not other way to do this.\n>\n> I spent an inordinate amount of time trying to answer that question a\n> decade ago, and my conclusion after trying every possible combination\n> is that it's simply not possible. Every solution at the end of the day\n> will be a hack that can be broken with a corner case. It has already\n> been discussed in this mailing list [1], and nobody found a solution.\n\nThat's what I have gathered from reading through that Stack Overflow\nthread as well.\n\n> That's why I wrote a patch to implement a branch@{tail} helper to show\n> an auxiliary ref to the beginning of the branch. I don't think I ever\n> sent it to the mailing list, as my patches are rarely merged, but I'm\n> sure I have it somewhere.\n\nThat would be interesting for the world to see, I bet, if only as a\nfuture reference to avoid other people trying to bang their head on the\nproblem the same way. :)\n\n> The other solution I thought of was adding an update-branch hook that\n> could be run every time a branch is updated, and then the hook would\n> update the branch tail reference [2]. As expected, that patch wasn't\n> merged either.\n\nThat seems like a major change in workflow though, adding basically a\nnew ref for each branch, right?\n\n> It's interesting how we keep coming back to the same problems; right\n> now there's a discussion in the git-users mailing list precisely about\n> the same topic: how to find the branch point, in particular so `git\n> name-rev` shows the correct branch a commit belongs to (which is\n> otherwise just a bad guess).\n\nWell, it's a need people certainly seem to have. :)\n\nI feel we are letting perfection be the enemy of good here. No, there\nare no solutions that work for the general case, you always find a\ncorner case that breaks it. But what if we could have a simple solution\nthat works for *most* cases and then *fails* gracefully for the corner\ncases?\n\nIn the case of the pre-push hook, specifically, we don't absolutely need\nsomething completely rock solid; if your branches are a mess of merges\nand cherry-picks and cross merges, yes, it might get confused but it's\nnot like it's going to lose a commit or something. The worse case is\nthat it's going to miss *checking* a commit and for this case it's not\nsatisfying, but it's also not data loss.\n\n> FWIW my motivation at the time was to prove Mercurial users wrong\n> regarding features that they have and Git doesn't, I contended that\n> Mercurial named branches (aka commit labels) were not necessary, and\n> everything they achieved could be achieved in Git through different\n> means. That turned out to be untrue, as there is one thing Mercurial\n> can do that Git can't: show the precise point a branch started from.\n\nI have given up on Mercurial a long, long time ago. It's extremely rare\nthat I find myself in such a situation and typically, there various\nhacks that answer the need without going into too much complexity.\n\nThe only reason I raise the issue here is because I wasn't satisfied\nhardcoding \"master\" (or main, for that matter) in the hook because I\nwanted a more generic answer. I suspect many people could be perfectly\nfine with hardcoding that in their hook or, failing that, with the\nincomplete heuristic I am proposing.\n\nOr they could even have a per-branch .git/config entry to map the branch\nto an upstream branch, and *that* could even \"default\" to \"main\" or\nwhatever that setting is called now. :)\n\nA.\n"},{"id":"473392","messageId":"CAMP44s30GBC7PFovzgaORMLLGYW=1mFVG4WH-dUfUW5-1sMd1Q@mail.gmail.com","threadId":"59371","inReplyTo":"87356ctvta.fsf@angela.anarc.at","subject":"Re: [RFC PATCH] hooks--pre-push.sample: identify branch point","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2023-03-10T22:09:43Z","receivedAt":"2023-03-10T22:11:02Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Mar 10, 2023 at 10:28 AM Antoine Beaupré <anarcat@debian.org> wrote:\n>\n> On 2023-03-09 17:22:55, Felipe Contreras wrote:\n> > Hi Antoine,\n> >\n> > On Thu, Mar 9, 2023 at 4:34 PM Antoine Beaupré <anarcat@debian.org> wrote:\n> >\n> >> https://stackoverflow.com/a/71193866/1174784\n> >>\n> >> There are currently a whopping twenty-five answers to that question in\n> >> that thread, and I'm hoping the community here will have a more\n> >> definitive answer to this question. I have picked the answer that uses\n> >> the least possible external commands, but it still uses a `tail -1`\n> >> which I'm somewhat unhappy about. I have thought of using\n> >> `--max-count` for this instead, but I understand that probably does\n> >> the equivalent of a `head -n` *and* it's applied before `--reverse`,\n> >> so there's not other way to do this.\n> >\n> > I spent an inordinate amount of time trying to answer that question a\n> > decade ago, and my conclusion after trying every possible combination\n> > is that it's simply not possible. Every solution at the end of the day\n> > will be a hack that can be broken with a corner case. It has already\n> > been discussed in this mailing list [1], and nobody found a solution.\n>\n> That's what I have gathered from reading through that Stack Overflow\n> thread as well.\n>\n> > That's why I wrote a patch to implement a branch@{tail} helper to show\n> > an auxiliary ref to the beginning of the branch. I don't think I ever\n> > sent it to the mailing list, as my patches are rarely merged, but I'm\n> > sure I have it somewhere.\n>\n> That would be interesting for the world to see, I bet, if only as a\n> future reference to avoid other people trying to bang their head on the\n> problem the same way. :)\n\nOK, I've rebased my patches on top of the current master (which wasn't\neasy) and sent them to the mailing list [1]. They are pretty hacky,\nbut they show what an actual solution could look like.\n\n> > The other solution I thought of was adding an update-branch hook that\n> > could be run every time a branch is updated, and then the hook would\n> > update the branch tail reference [2]. As expected, that patch wasn't\n> > merged either.\n>\n> That seems like a major change in workflow though, adding basically a\n> new ref for each branch, right?\n\nThere's no change in the workflow, the user keeps typing the same\ncommands, there's just extra information.\n\nBut yeah, every branch now has two refs.\n\n> > It's interesting how we keep coming back to the same problems; right\n> > now there's a discussion in the git-users mailing list precisely about\n> > the same topic: how to find the branch point, in particular so `git\n> > name-rev` shows the correct branch a commit belongs to (which is\n> > otherwise just a bad guess).\n>\n> Well, it's a need people certainly seem to have. :)\n>\n> I feel we are letting perfection be the enemy of good here. No, there\n> are no solutions that work for the general case, you always find a\n> corner case that breaks it. But what if we could have a simple solution\n> that works for *most* cases and then *fails* gracefully for the corner\n> cases?\n\nI did propose such a solution, I wrote extensive tests to make sure it\nworked properly, but it was largely ignored [2].\n\nThe solution with --exclude-first-parent-only fails my tests in a very\ncomplex case:\n\n   X (master)\n    \\\n     A (topic)\n\nSure, it's probably easy to fix, but the point is that a reliable and\nrobust solution everyone agrees with doesn't exist.\n\n> In the case of the pre-push hook, specifically, we don't absolutely need\n> something completely rock solid; if your branches are a mess of merges\n> and cherry-picks and cross merges, yes, it might get confused but it's\n> not like it's going to lose a commit or something. The worse case is\n> that it's going to miss *checking* a commit and for this case it's not\n> satisfying, but it's also not data loss.\n\nBut I bet you want the simple case of a sequence of commits with no\nmerges to properly detect something.\n\n> > FWIW my motivation at the time was to prove Mercurial users wrong\n> > regarding features that they have and Git doesn't, I contended that\n> > Mercurial named branches (aka commit labels) were not necessary, and\n> > everything they achieved could be achieved in Git through different\n> > means. That turned out to be untrue, as there is one thing Mercurial\n> > can do that Git can't: show the precise point a branch started from.\n>\n> I have given up on Mercurial a long, long time ago. It's extremely rare\n> that I find myself in such a situation and typically, there various\n> hacks that answer the need without going into too much complexity.\n>\n> The only reason I raise the issue here is because I wasn't satisfied\n> hardcoding \"master\" (or main, for that matter) in the hook because I\n> wanted a more generic answer. I suspect many people could be perfectly\n> fine with hardcoding that in their hook or, failing that, with the\n> incomplete heuristic I am proposing.\n>\n> Or they could even have a per-branch .git/config entry to map the branch\n> to an upstream branch, and *that* could even \"default\" to \"main\" or\n> whatever that setting is called now. :)\n\nSounds like you are talking about the upstream tracking branch [3].\nAre you familiar with that?\n\nCheers.\n\n[1] https://lore.kernel.org/git/20230310214515.39154-1-felipe.contreras@gmail.com/\n[2] https://stackoverflow.com/a/10821591/10474\n[3] https://felipec.wordpress.com/2013/09/01/advanced-git-concepts-the-upstream-tracking-branch/\n\n-- \nFelipe Contreras\n"},{"id":"473418","messageId":"87lek1suqb.fsf@angela.anarc.at","threadId":"59371","inReplyTo":"CAMP44s30GBC7PFovzgaORMLLGYW=1mFVG4WH-dUfUW5-1sMd1Q@mail.gmail.com","subject":"Re: [RFC PATCH] hooks--pre-push.sample: identify branch point","fromName":"Antoine Beaupré","fromEmail":"anarcat@debian.org","sentAt":"2023-03-12T18:14:04Z","receivedAt":"2023-03-12T18:27:37Z","isPatch":true,"sender":{"key":"anarcat@debian.org","avatar":"https://avatars.githubusercontent.com/u/796623?v=4"},"body":"On 2023-03-10 16:09:43, Felipe Contreras wrote:\n> On Fri, Mar 10, 2023 at 10:28 AM Antoine Beaupré <anarcat@debian.org> wrote:\n>>\n>> On 2023-03-09 17:22:55, Felipe Contreras wrote:\n>> > Hi Antoine,\n>> >\n>> > On Thu, Mar 9, 2023 at 4:34 PM Antoine Beaupré <anarcat@debian.org> wrote:\n>> >\n\n[...]\n\n>> > It's interesting how we keep coming back to the same problems; right\n>> > now there's a discussion in the git-users mailing list precisely about\n>> > the same topic: how to find the branch point, in particular so `git\n>> > name-rev` shows the correct branch a commit belongs to (which is\n>> > otherwise just a bad guess).\n>>\n>> Well, it's a need people certainly seem to have. :)\n>>\n>> I feel we are letting perfection be the enemy of good here. No, there\n>> are no solutions that work for the general case, you always find a\n>> corner case that breaks it. But what if we could have a simple solution\n>> that works for *most* cases and then *fails* gracefully for the corner\n>> cases?\n>\n> I did propose such a solution, I wrote extensive tests to make sure it\n> worked properly, but it was largely ignored [2].\n>\n> The solution with --exclude-first-parent-only fails my tests in a very\n> complex case:\n>\n>    X (master)\n>     \\\n>      A (topic)\n>\n> Sure, it's probably easy to fix, but the point is that a reliable and\n> robust solution everyone agrees with doesn't exist.\n\nHm... that's odd, I'm surprised that doesn't work. But that's certainly\na \"special\" (!) case that should be handled properly.\n\n[...]\n\n>> Or they could even have a per-branch .git/config entry to map the branch\n>> to an upstream branch, and *that* could even \"default\" to \"main\" or\n>> whatever that setting is called now. :)\n>\n> Sounds like you are talking about the upstream tracking branch [3].\n> Are you familiar with that?\n\nNo, I'm not refering to branch.NAME.upstream here, sorry if my use of\n\"upstream\" here was confusing. I mean \"the branch this branch has been\nforked from\" not \"the upstream equivalent to this local branch\".\n\na.\n\n-- \nScience knows still practically nothing about the real nature of\nmatter, energy, dimension, or time; and even less about those\nremarkable things called life and thought. But whatever the meaning\nand purpose of this universe, you are a legitimate part of it.\n                        - Gene Roddenberry\n"},{"id":"473601","messageId":"CAMP44s12i0nzSKd4reJf_51=BgrGVD3xpsDzYHGJOO11FcvjCA@mail.gmail.com","threadId":"59371","inReplyTo":"87lek1suqb.fsf@angela.anarc.at","subject":"Re: [RFC PATCH] hooks--pre-push.sample: identify branch point","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2023-03-16T17:32:47Z","receivedAt":"2023-03-16T17:33:15Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Sun, Mar 12, 2023 at 12:14 PM Antoine Beaupré <anarcat@debian.org> wrote:\n>\n> On 2023-03-10 16:09:43, Felipe Contreras wrote:\n> > On Fri, Mar 10, 2023 at 10:28 AM Antoine Beaupré <anarcat@debian.org> wrote:\n> >>\n> >> On 2023-03-09 17:22:55, Felipe Contreras wrote:\n> >> > Hi Antoine,\n> >> >\n> >> > On Thu, Mar 9, 2023 at 4:34 PM Antoine Beaupré <anarcat@debian.org> wrote:\n> >> >\n>\n> [...]\n>\n> >> > It's interesting how we keep coming back to the same problems; right\n> >> > now there's a discussion in the git-users mailing list precisely about\n> >> > the same topic: how to find the branch point, in particular so `git\n> >> > name-rev` shows the correct branch a commit belongs to (which is\n> >> > otherwise just a bad guess).\n> >>\n> >> Well, it's a need people certainly seem to have. :)\n> >>\n> >> I feel we are letting perfection be the enemy of good here. No, there\n> >> are no solutions that work for the general case, you always find a\n> >> corner case that breaks it. But what if we could have a simple solution\n> >> that works for *most* cases and then *fails* gracefully for the corner\n> >> cases?\n> >\n> > I did propose such a solution, I wrote extensive tests to make sure it\n> > worked properly, but it was largely ignored [2].\n> >\n> > The solution with --exclude-first-parent-only fails my tests in a very\n> > complex case:\n> >\n> >    X (master)\n> >     \\\n> >      A (topic)\n> >\n> > Sure, it's probably easy to fix, but the point is that a reliable and\n> > robust solution everyone agrees with doesn't exist.\n>\n> Hm... that's odd, I'm surprised that doesn't work. But that's certainly\n> a \"special\" (!) case that should be handled properly.\n\nThat's because the command wasn't meant to be called from a script,\nbut by a human who knows what he is doing.\n\nTo make it into a command that \"just works\" regardless of the\nsituation some work would be needed to make sure it works in all the\ncases people have already debated.\n\nMy command just works, I would be willing to do the work of\ninvestigating if  --exclude-first-parent-only could be used instead,\nbut it's not very tempting to do that work again if it's going to be\nignored again.\n\n> >> Or they could even have a per-branch .git/config entry to map the branch\n> >> to an upstream branch, and *that* could even \"default\" to \"main\" or\n> >> whatever that setting is called now. :)\n> >\n> > Sounds like you are talking about the upstream tracking branch [3].\n> > Are you familiar with that?\n>\n> No, I'm not refering to branch.NAME.upstream here, sorry if my use of\n> \"upstream\" here was confusing. I mean \"the branch this branch has been\n> forked from\" not \"the upstream equivalent to this local branch\".\n\nUnfortunately Git conflates two different concepts into @{upstream}:\nthe branch we want to rebase to, and the branch we want to be merged\nto. By \"upstream\" I meant the upstream tracking branch when it's\nconfigured to the branch we want to rebase to. For example:\n\n  git switch --create topic --track master\n\nIn this case topic@{u} is the branch that we forked from.\n\nIn my fork of git I de-conflate these two concepts, which are clearly\ndifferent: @{upstream} versus @{publish}.\n\nIn my personal workflow @{upstream} is *always* the branch I forked\nfrom, and I want to rebase to, and when it's not configured \"master\"\nis a safe default.\n\nBecause it's tedious to do this check every time, I have a script to\nbasically do:\n\n  local u=\"${branch}@{u}\"\n  git rev-parse --verify --quiet \"$u\" || u=master\n  echo \"${u}..$branch\"\n\nIt would be nice if git supported @{upstream|default} or even better: @{base}.\n\nCheers.\n\n-- \nFelipe Contreras\n"}]}