{"thread":{"id":"62379","subject":"[RFC PATCH] object-name: add @{upstreamhead} shorthand","startedAt":"2024-10-20T20:25:41Z","lastAt":"2024-10-28T05:33:16Z","messageCount":14,"participants":["Bence Ferdinandy","Kristoffer Haugsbakk","Jeff King","Taylor Blau"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"505577","messageId":"20241020202507.2596990-1-bence@ferdinandy.com","threadId":"62379","inReplyTo":null,"subject":"[RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Bence Ferdinandy","fromEmail":"bence@ferdinandy.com","sentAt":"2024-10-20T20:24:48Z","receivedAt":"2024-10-20T20:25:41Z","isPatch":true,"sender":{"key":"bence@ferdinandy.com","avatar":"https://avatars.githubusercontent.com/u/6343487?v=4"},"body":"The HEAD of the remote is useful in many situations, but currently one\nwould need to know the name of the remote to perform something like\n\"git log origin/HEAD..\", which makes writing remote agnostic aliases\ncomplicated. Introduce the new shorthand \"@{upstreamhead}\" which returns\n<remote>/HEAD for the same <remote> \"@{upstream}\" would yield.\n\nSigned-off-by: Bence Ferdinandy <bence@ferdinandy.com>\n---\n\nNotes:\n    RFC v1: Testing and documentation is completely missing, I'll add those\n            in a v2 if people think the patch has merit.\n\n object-name.c | 15 ++++++++++++++-\n remote.c      | 36 ++++++++++++++++++++++++++++++++++++\n remote.h      |  8 ++++++++\n 3 files changed, 58 insertions(+), 1 deletion(-)\n\ndiff --git a/object-name.c b/object-name.c\nindex c892fbe80a..f40a226a57 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -936,6 +936,12 @@ static inline int push_mark(const char *string, int len)\n \treturn at_mark(string, len, suffix, ARRAY_SIZE(suffix));\n }\n \n+static inline int upstream_head_mark(const char *string, int len)\n+{\n+\tconst char *suffix[] = { \"@{upstreamhead}\", \"@{uh}\" };\n+\treturn at_mark(string, len, suffix, ARRAY_SIZE(suffix));\n+}\n+\n static enum get_oid_result get_oid_1(struct repository *r, const char *name, int len, struct object_id *oid, unsigned lookup_flags);\n static int interpret_nth_prior_checkout(struct repository *r, const char *name, int namelen, struct strbuf *buf);\n \n@@ -985,7 +991,8 @@ static int get_oid_basic(struct repository *r, const char *str, int len,\n \t\t\t\t\tcontinue;\n \t\t\t\t}\n \t\t\t\tif (!upstream_mark(str + at, len - at) &&\n-\t\t\t\t    !push_mark(str + at, len - at)) {\n+\t\t\t\t    !push_mark(str + at, len - at) &&\n+\t\t\t\t    !upstream_head_mark(str + at, len - at)) {\n \t\t\t\t\treflog_len = (len-1) - (at+2);\n \t\t\t\t\tlen = at;\n \t\t\t\t}\n@@ -1729,6 +1736,12 @@ int repo_interpret_branch_name(struct repository *r,\n \t\t\t\t\t    options);\n \t\tif (len > 0)\n \t\t\treturn len;\n+\n+\t\tlen = interpret_branch_mark(r, name, namelen, at - name, buf,\n+\t\t\t\t\t    upstream_head_mark, branch_get_upstream_head,\n+\t\t\t\t\t    options);\n+\t\tif (len > 0)\n+\t\t\treturn len;\n \t}\n \n \treturn -1;\ndiff --git a/remote.c b/remote.c\nindex 10104d11e3..302f013a25 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1980,6 +1980,42 @@ const char *branch_get_upstream(struct branch *branch, struct strbuf *err)\n \treturn branch->merge[0]->dst;\n }\n \n+const char *branch_get_upstream_head(struct branch *branch, struct strbuf *err)\n+{\n+\tstruct strbuf retval = STRBUF_INIT, refstring = STRBUF_INIT;\n+\tstruct string_list l = STRING_LIST_INIT_DUP;\n+\n+\tif (!branch)\n+\t\treturn error_buf(err, _(\"HEAD does not point to a branch\"));\n+\n+\tif (!branch->merge || !branch->merge[0]) {\n+\t\t/*\n+\t\t * no merge config; is it because the user didn't define any,\n+\t\t * or because it is not a real branch, and get_branch\n+\t\t * auto-vivified it?\n+\t\t */\n+\t\tif (!refs_ref_exists(get_main_ref_store(the_repository), branch->refname))\n+\t\t\treturn error_buf(err, _(\"no such branch: '%s'\"),\n+\t\t\t\t\t branch->name);\n+\t\treturn error_buf(err,\n+\t\t\t\t _(\"no upstream configured for branch '%s'\"),\n+\t\t\t\t branch->name);\n+\t}\n+\n+\tif (!branch->merge[0]->dst)\n+\t\treturn error_buf(err,\n+\t\t\t\t _(\"upstream branch '%s' not stored as a remote-tracking branch\"),\n+\t\t\t\t branch->merge[0]->src);\n+\n+\tstring_list_split(&l, branch->merge[0]->dst, '/', -1);\n+\tstrbuf_addf(&refstring, \"refs/remotes/%s/HEAD\", l.items[2].string);\n+\n+\tif (refs_read_symbolic_ref(get_main_ref_store(the_repository), refstring.buf, &retval))\n+\t\t\treturn error_buf(err, _(\"%s does not exist\"), refstring.buf);\n+\n+\treturn retval.buf;\n+}\n+\n static const char *tracking_for_push_dest(struct remote *remote,\n \t\t\t\t\t  const char *refname,\n \t\t\t\t\t  struct strbuf *err)\ndiff --git a/remote.h b/remote.h\nindex a7e5c4e07c..a1d0f44297 100644\n--- a/remote.h\n+++ b/remote.h\n@@ -360,6 +360,14 @@ const char *branch_get_upstream(struct branch *branch, struct strbuf *err);\n  */\n const char *branch_get_push(struct branch *branch, struct strbuf *err);\n \n+/**\n+ * Return the fully-qualified refname of the HEAD branch for the same remote\n+ * that \"branch@{upstream}\" is on.\n+ *\n+ * The return value and `err` conventions match those of `branch_get_upstream`.\n+ */\n+const char *branch_get_upstream_head(struct branch *branch, struct strbuf *err);\n+\n /* Flags to match_refs. */\n enum match_refs_flags {\n \tMATCH_REFS_NONE\t\t= 0,\n-- \n2.47.0.94.gc947641c25\n\n"},{"id":"505578","messageId":"1c056d39-950c-4965-89d6-85f0c2c1bccd@app.fastmail.com","threadId":"62379","inReplyTo":"20241020202507.2596990-1-bence@ferdinandy.com","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Kristoffer Haugsbakk","fromEmail":"kristofferhaugsbakk@fastmail.com","sentAt":"2024-10-20T20:40:27Z","receivedAt":"2024-10-20T20:40:48Z","isPatch":true,"sender":{"key":"kristofferhaugsbakk@fastmail.com","avatar":null},"body":"Good evening\n\nOn Sun, Oct 20, 2024, at 22:24, Bence Ferdinandy wrote:\n> The HEAD of the remote is useful in many situations, but currently one\n> would need to know the name of the remote to perform something like\n> \"git log origin/HEAD..\", which makes writing remote agnostic aliases\n> complicated. Introduce the new shorthand \"@{upstreamhead}\" which returns\n> <remote>/HEAD for the same <remote> \"@{upstream}\" would yield.\n>\n> Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>\n> ---\n>\n> Notes:\n>     RFC v1: Testing and documentation is completely missing, I'll add those\n>             in a v2 if people think the patch has merit.\n\nDo you have some concrete examples?  I’m not well versed in using\nremote HEAD.\n\n-- \nKristoffer Haugsbakk\n\n"},{"id":"505580","messageId":"D50YLOBHJTLS.367TMAOLKL019@ferdinandy.com","threadId":"62379","inReplyTo":"1c056d39-950c-4965-89d6-85f0c2c1bccd@app.fastmail.com","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Bence Ferdinandy","fromEmail":"bence@ferdinandy.com","sentAt":"2024-10-20T21:42:38Z","receivedAt":"2024-10-20T21:43:31Z","isPatch":true,"sender":{"key":"bence@ferdinandy.com","avatar":"https://avatars.githubusercontent.com/u/6343487?v=4"},"body":"\nOn Sun Oct 20, 2024 at 22:40, Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com> wrote:\n> Good evening\n>\n> On Sun, Oct 20, 2024, at 22:24, Bence Ferdinandy wrote:\n>> The HEAD of the remote is useful in many situations, but currently one\n>> would need to know the name of the remote to perform something like\n>> \"git log origin/HEAD..\", which makes writing remote agnostic aliases\n>> complicated. Introduce the new shorthand \"@{upstreamhead}\" which returns\n>> <remote>/HEAD for the same <remote> \"@{upstream}\" would yield.\n>>\n>> Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>\n>> ---\n>>\n>> Notes:\n>>     RFC v1: Testing and documentation is completely missing, I'll add those\n>>             in a v2 if people think the patch has merit.\n>\n> Do you have some concrete examples?  I’m not well versed in using\n> remote HEAD.\n\nN.b. I was intending to write s/many situations/some situations.\n\nI basically use it for two things:\n\n- variations of `git log remote/HEAD..` for which I currently have an alias\n  with \"origin\" hardcoded. E.g. I'm on a feature branch I'm reviewing and\n  I want to know what commits are new compared to origin/(master|main|trunk),\n  but I use HEAD, because I never know (and don't really want to pay attention\n  to) what project uses what. And although \"origin\" is usually ok, but not\n  always if there are forks in play, so @{upstreamhead} would make it agnostic\n  to the remote's name.\n- I also use remote/HEAD in CICD, i.e. with `git rev-list origin/HEAD..` you\n  can run checks on a commit-by-commit bases instead of the end result of\n  a patch series or pull request. It's really useful to check have basic checks\n  for commit messages for example. In a CICD of course for a _specific_ project\n  you know what HEAD is, but still, using HEAD makes a step portable across\n  repos. And again of course, I think in CICD you almost certainly will always\n  end up with the remote being called \"origin\", so this change might not be\n  quite so useful there.\n\nBut so the long story short here is that for\n(origin|upstream)/(master|main|trunk) we can already have agnostic code with\nHEAD for the second part and with a patch like this we could have agnostic code\nfor the whole thing.\n\nBest,\nBence\n\n-- \nbence.ferdinandy.com\n\n"},{"id":"505726","messageId":"20241021191441.GD1219228@coredump.intra.peff.net","threadId":"62379","inReplyTo":"D50YLOBHJTLS.367TMAOLKL019@ferdinandy.com","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2024-10-21T19:14:41Z","receivedAt":"2024-10-21T19:14:43Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Oct 20, 2024 at 11:42:38PM +0200, Bence Ferdinandy wrote:\n\n> I basically use it for two things:\n> \n> - variations of `git log remote/HEAD..` for which I currently have an alias\n>   with \"origin\" hardcoded. E.g. I'm on a feature branch I'm reviewing and\n>   I want to know what commits are new compared to origin/(master|main|trunk),\n>   but I use HEAD, because I never know (and don't really want to pay attention\n>   to) what project uses what. And although \"origin\" is usually ok, but not\n>   always if there are forks in play, so @{upstreamhead} would make it agnostic\n>   to the remote's name.\n\nI'm a little skeptical that this is useful. If a local branch has a\nparticular remote branch configured as its upstream, then shouldn't your\nsearch for new commits be against that configured upstream branch, not\nwhatever that remote's HEAD happens to be?\n\nIn many cases, of course, I'd expect that HEAD to also be the upstream\nbranch. But then you could just use @{upstream}.\n\nAnd in some cases, you really want to compare against a known base\npoint, regardless of the configured upstream. But then you should use\nthe full name of that base point, rather than the remote half of the\nupstream config.\n\nIt sounds more like a band-aid for scripts that are expected to be used\nacross repos that may use other names for what is effectively \"origin\".\nIn which case I question whether we really want new lookup syntax,\nversus having those scripts learn to query the remote name.\n\nE.g., I think you could do:\n\n  upstream=$(git rev-parse --symbolic-full-name @{upstream})\n  git log ${upstream%/*}/HEAD..\n\nAnd possibly we could make it easier to just grab the remote name with a\nsingle command.\n\n-Peff\n"},{"id":"505732","messageId":"ZxavVmjsshVHCPcL@nand.local","threadId":"62379","inReplyTo":"D50YLOBHJTLS.367TMAOLKL019@ferdinandy.com","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2024-10-21T19:45:26Z","receivedAt":"2024-10-21T19:45:29Z","isPatch":true,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"On Sun, Oct 20, 2024 at 11:42:38PM +0200, Bence Ferdinandy wrote:\n> But so the long story short here is that for\n> (origin|upstream)/(master|main|trunk) we can already have agnostic code with\n> HEAD for the second part and with a patch like this we could have agnostic code\n> for the whole thing.\n\nI'm hesitant to pick this up because of what is said in this paragraph.\nWhen you write \"(master|main|trunk)\", I think you're really spelling\n\"HEAD\". And it's fine to write HEAD in a script when you want to resolve\nsomething to master/main/trunk/etc. without caring which and instead\ndelegating that to whatever the remote HEAD is.\n\nBut determining the upstream of a branch is already easy to do as Peff\npoints out downthread. So this seems like a band-aid for scripts that do\nnot care to perform such a resolution themselves.\n\nThanks,\nTaylor\n"},{"id":"505743","messageId":"D51R90BTHJMY.1C1XY5P4CHTWG@ferdinandy.com","threadId":"62379","inReplyTo":"20241021191441.GD1219228@coredump.intra.peff.net","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Bence Ferdinandy","fromEmail":"bence@ferdinandy.com","sentAt":"2024-10-21T20:09:38Z","receivedAt":"2024-10-21T20:10:09Z","isPatch":true,"sender":{"key":"bence@ferdinandy.com","avatar":"https://avatars.githubusercontent.com/u/6343487?v=4"},"body":"\nOn Mon Oct 21, 2024 at 21:14, Jeff King <peff@peff.net> wrote:\n> On Sun, Oct 20, 2024 at 11:42:38PM +0200, Bence Ferdinandy wrote:\n>\n>> I basically use it for two things:\n>> \n>> - variations of `git log remote/HEAD..` for which I currently have an alias\n>>   with \"origin\" hardcoded. E.g. I'm on a feature branch I'm reviewing and\n>>   I want to know what commits are new compared to origin/(master|main|trunk),\n>>   but I use HEAD, because I never know (and don't really want to pay attention\n>>   to) what project uses what. And although \"origin\" is usually ok, but not\n>>   always if there are forks in play, so @{upstreamhead} would make it agnostic\n>>   to the remote's name.\n>\n> I'm a little skeptical that this is useful. If a local branch has a\n> particular remote branch configured as its upstream, then shouldn't your\n> search for new commits be against that configured upstream branch, not\n> whatever that remote's HEAD happens to be?\n>\n> In many cases, of course, I'd expect that HEAD to also be the upstream\n> branch. But then you could just use @{upstream}.\n>\n> And in some cases, you really want to compare against a known base\n> point, regardless of the configured upstream. But then you should use\n> the full name of that base point, rather than the remote half of the\n> upstream config.\n>\n> It sounds more like a band-aid for scripts that are expected to be used\n> across repos that may use other names for what is effectively \"origin\".\n> In which case I question whether we really want new lookup syntax,\n> versus having those scripts learn to query the remote name.\n>\n> E.g., I think you could do:\n>\n>   upstream=$(git rev-parse --symbolic-full-name @{upstream})\n>   git log ${upstream%/*}/HEAD..\n\nThat particular one will break if you have something like\nrefs/remotes/origin/foo/bar, but I get your point.\n\n>\n> And possibly we could make it easier to just grab the remote name with a\n> single command.\n\nAs I was running this patch through my head yesterday I sort of distilled my\nargument in favour to \"writing remote agnostic scripts are unnecessarily\ncomplicated\", but I do agree, that if there were a git command that could\nreturn the remote for a branch without any extra scripting hacks would easily\nget you the same result, and may even be useful elsewhere.\n\nI'm not sure where this would be the best. Maybe: \n\tgit branch --show-current-remote\n?\n\nThanks for the feedback!\n\nBest,\nBence\n\n-- \nbence.ferdinandy.com\n\n"},{"id":"505744","messageId":"D51RA8GNVDC9.1DBQYNQVHEP69@ferdinandy.com","threadId":"62379","inReplyTo":"ZxavVmjsshVHCPcL@nand.local","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Bence Ferdinandy","fromEmail":"bence@ferdinandy.com","sentAt":"2024-10-21T20:11:14Z","receivedAt":"2024-10-21T20:12:30Z","isPatch":true,"sender":{"key":"bence@ferdinandy.com","avatar":"https://avatars.githubusercontent.com/u/6343487?v=4"},"body":"\nOn Mon Oct 21, 2024 at 21:45, Taylor Blau <me@ttaylorr.com> wrote:\n> On Sun, Oct 20, 2024 at 11:42:38PM +0200, Bence Ferdinandy wrote:\n>> But so the long story short here is that for\n>> (origin|upstream)/(master|main|trunk) we can already have agnostic code with\n>> HEAD for the second part and with a patch like this we could have agnostic code\n>> for the whole thing.\n>\n> I'm hesitant to pick this up because of what is said in this paragraph.\n> When you write \"(master|main|trunk)\", I think you're really spelling\n> \"HEAD\". And it's fine to write HEAD in a script when you want to resolve\n> something to master/main/trunk/etc. without caring which and instead\n> delegating that to whatever the remote HEAD is.\n>\n> But determining the upstream of a branch is already easy to do as Peff\n> points out downthread. So this seems like a band-aid for scripts that do\n> not care to perform such a resolution themselves.\n\nAgreed, Peff's idea to make querying remote easier is a much better way.\n\nBest,\nBence\n\n-- \nbence.ferdinandy.com\n\n"},{"id":"505747","messageId":"Zxa6/4D8lWgqqaxM@nand.local","threadId":"62379","inReplyTo":"D51R90BTHJMY.1C1XY5P4CHTWG@ferdinandy.com","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2024-10-21T20:35:11Z","receivedAt":"2024-10-21T20:35:14Z","isPatch":true,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"On Mon, Oct 21, 2024 at 10:09:38PM +0200, Bence Ferdinandy wrote:\n> > E.g., I think you could do:\n> >\n> >   upstream=$(git rev-parse --symbolic-full-name @{upstream})\n> >   git log ${upstream%/*}/HEAD..\n>\n> That particular one will break if you have something like\n> refs/remotes/origin/foo/bar, but I get your point.\n\nUgh. Having / characters in remote names feels like a mistake to me ;-).\n\nThanks,\nTaylor\n"},{"id":"505987","messageId":"20241023215618.GA821188@coredump.intra.peff.net","threadId":"62379","inReplyTo":"D51R90BTHJMY.1C1XY5P4CHTWG@ferdinandy.com","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2024-10-23T21:56:18Z","receivedAt":"2024-10-23T21:56:27Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Oct 21, 2024 at 10:09:38PM +0200, Bence Ferdinandy wrote:\n\n> > And possibly we could make it easier to just grab the remote name with a\n> > single command.\n> \n> As I was running this patch through my head yesterday I sort of distilled my\n> argument in favour to \"writing remote agnostic scripts are unnecessarily\n> complicated\", but I do agree, that if there were a git command that could\n> return the remote for a branch without any extra scripting hacks would easily\n> get you the same result, and may even be useful elsewhere.\n> \n> I'm not sure where this would be the best. Maybe: \n> \tgit branch --show-current-remote\n> ?\n\nI've been giving some thought to this.\n\nYou could argue it's about querying remotes, so \"git remote\". Although\nwe don't really want to know anything about the remote except its name,\nso it's a little weird.\n\nOr as you note, we're querying info about a branch. So \"git branch\"\nmakes sense.  But \"--show-current-remote\" feels kind of narrow there.\nShouldn't we be able to ask about the configured remote for any branch?\n\nIn which case it is really just a single \"git config\" lookup away:\n\n  git config branch.$branch.remote\n\nYou have to look up the current branch, of course. You can do that with\nsymbolic-ref like:\n\n  git config \"branch.$(git symbolic-ref --short HEAD).remote\"\n\nYou might get an error from symbolic-ref if we're on a detached HEAD, of\ncourse.  You can either ignore that (in which case the lookup of\n\"branch..remote\" would show nothing), or a script can actually\ndistinguish the two cases (\"not on a branch\" versus \"there is no\nconfigured remote\").\n\nThere's also another wrinkle we hadn't discussed: we have the concept of\nboth an upstream remote for fetching and a push remote. And this would\nnaturally extend there (you'd ask for .pushremote instead).\n\nAnd finally, there's yet another way to access this information. ;) The\nfor-each-ref formatter (which is also used for \"branch --format\") knows\nhow to show remote names (and much more). So:\n\n  git branch --list --format='%(upstream:remotename)' $branch\n\nalso gets you what you want. I don't think there's a good way to ask\nthat command to show just the branch pointed to by HEAD, though. We\nrecently added --include-root-refs to for-each-ref, but that's not quite\nwhat you want (you want just HEAD, and you really want to dereference it\nto show details of the branch it points to).\n\nSo I think rather than \"branch --show-current-remote\", we'd want\nsome option to make \"branch --list\" show only the currently checked out\nbranch, and then you could apply --format to it to get whatever\ninformation you wanted. Something like:\n\n  git branch --list --is-head --format='%(upstream:remotename)'\n\n-Peff\n"},{"id":"506062","messageId":"D549EIKDKGDS.2AETZLT4RTB44@ferdinandy.com","threadId":"62379","inReplyTo":"20241023215618.GA821188@coredump.intra.peff.net","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Bence Ferdinandy","fromEmail":"bence@ferdinandy.com","sentAt":"2024-10-24T18:48:29Z","receivedAt":"2024-10-24T18:49:15Z","isPatch":true,"sender":{"key":"bence@ferdinandy.com","avatar":"https://avatars.githubusercontent.com/u/6343487?v=4"},"body":"\nOn Wed Oct 23, 2024 at 23:56, Jeff King <peff@peff.net> wrote:\n> On Mon, Oct 21, 2024 at 10:09:38PM +0200, Bence Ferdinandy wrote:\n>\n>> > And possibly we could make it easier to just grab the remote name with a\n>> > single command.\n>> \n>> As I was running this patch through my head yesterday I sort of distilled my\n>> argument in favour to \"writing remote agnostic scripts are unnecessarily\n>> complicated\", but I do agree, that if there were a git command that could\n>> return the remote for a branch without any extra scripting hacks would easily\n>> get you the same result, and may even be useful elsewhere.\n>> \n>> I'm not sure where this would be the best. Maybe: \n>> \tgit branch --show-current-remote\n>> ?\n>\n> I've been giving some thought to this.\n>\n> You could argue it's about querying remotes, so \"git remote\". Although\n> we don't really want to know anything about the remote except its name,\n> so it's a little weird.\n>\n> Or as you note, we're querying info about a branch. So \"git branch\"\n> makes sense.  But \"--show-current-remote\" feels kind of narrow there.\n> Shouldn't we be able to ask about the configured remote for any branch?\n>\n> In which case it is really just a single \"git config\" lookup away:\n>\n>   git config branch.$branch.remote\n>\n> You have to look up the current branch, of course. You can do that with\n> symbolic-ref like:\n>\n>   git config \"branch.$(git symbolic-ref --short HEAD).remote\"\n>\n> You might get an error from symbolic-ref if we're on a detached HEAD, of\n> course.  You can either ignore that (in which case the lookup of\n> \"branch..remote\" would show nothing), or a script can actually\n> distinguish the two cases (\"not on a branch\" versus \"there is no\n> configured remote\").\n>\n> There's also another wrinkle we hadn't discussed: we have the concept of\n> both an upstream remote for fetching and a push remote. And this would\n> naturally extend there (you'd ask for .pushremote instead).\n>\n> And finally, there's yet another way to access this information. ;) The\n> for-each-ref formatter (which is also used for \"branch --format\") knows\n> how to show remote names (and much more). So:\n>\n>   git branch --list --format='%(upstream:remotename)' $branch\n>\n> also gets you what you want. I don't think there's a good way to ask\n> that command to show just the branch pointed to by HEAD, though. We\n> recently added --include-root-refs to for-each-ref, but that's not quite\n> what you want (you want just HEAD, and you really want to dereference it\n> to show details of the branch it points to).\n>\n> So I think rather than \"branch --show-current-remote\", we'd want\n> some option to make \"branch --list\" show only the currently checked out\n> branch, and then you could apply --format to it to get whatever\n> information you wanted. Something like:\n>\n>   git branch --list --is-head --format='%(upstream:remotename)'\n\nThanks for running through this in such detail! This would be more widely\nuseful for sure. \n\nI'd probably call the flag something like \"--current\", \"--current-only\" rather\nthan \"--is-head\" though. \"--is-head\" sounds as if it would filter --list but\nnot necessarily end up with a single entry.\n\nAnyway, thanks for the idea, I'll probably pick this up sooner or later.\n\nBest,\nBence\n\n\n-- \nbence.ferdinandy.com\n\n"},{"id":"506081","messageId":"20241025062438.GA2107756@coredump.intra.peff.net","threadId":"62379","inReplyTo":"D549EIKDKGDS.2AETZLT4RTB44@ferdinandy.com","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2024-10-25T06:24:38Z","receivedAt":"2024-10-25T06:24:47Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Oct 24, 2024 at 08:48:29PM +0200, Bence Ferdinandy wrote:\n\n> > So I think rather than \"branch --show-current-remote\", we'd want\n> > some option to make \"branch --list\" show only the currently checked out\n> > branch, and then you could apply --format to it to get whatever\n> > information you wanted. Something like:\n> >\n> >   git branch --list --is-head --format='%(upstream:remotename)'\n> \n> Thanks for running through this in such detail! This would be more widely\n> useful for sure. \n> \n> I'd probably call the flag something like \"--current\", \"--current-only\" rather\n> than \"--is-head\" though. \"--is-head\" sounds as if it would filter --list but\n> not necessarily end up with a single entry.\n\nYeah, I think --current would be fine.\n\n-Peff\n"},{"id":"506165","messageId":"D56XI8GBH2GF.3MP02MGQGP5M@ferdinandy.com","threadId":"62379","inReplyTo":"20241025062438.GA2107756@coredump.intra.peff.net","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Bence Ferdinandy","fromEmail":"bence@ferdinandy.com","sentAt":"2024-10-27T22:07:07Z","receivedAt":"2024-10-27T22:07:39Z","isPatch":true,"sender":{"key":"bence@ferdinandy.com","avatar":"https://avatars.githubusercontent.com/u/6343487?v=4"},"body":"\nOn Fri Oct 25, 2024 at 08:24, Jeff King <peff@peff.net> wrote:\n> On Thu, Oct 24, 2024 at 08:48:29PM +0200, Bence Ferdinandy wrote:\n>\n>> > So I think rather than \"branch --show-current-remote\", we'd want\n>> > some option to make \"branch --list\" show only the currently checked out\n>> > branch, and then you could apply --format to it to get whatever\n>> > information you wanted. Something like:\n>> >\n>> >   git branch --list --is-head --format='%(upstream:remotename)'\n>> \n>> Thanks for running through this in such detail! This would be more widely\n>> useful for sure. \n>> \n>> I'd probably call the flag something like \"--current\", \"--current-only\" rather\n>> than \"--is-head\" though. \"--is-head\" sounds as if it would filter --list but\n>> not necessarily end up with a single entry.\n>\n> Yeah, I think --current would be fine.\n\nI was looking through git branch and there is a --show-current option. I was\nwondering, would it not be better to teach --show-current to also obey\n--format? It would avoid having a \"--current\" that only works with \"--list\"\nbesides having a \"--show-current\".\n"},{"id":"506171","messageId":"Zx7QkaQ5IKxQFskK@nand.local","threadId":"62379","inReplyTo":"D56XI8GBH2GF.3MP02MGQGP5M@ferdinandy.com","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2024-10-27T23:45:21Z","receivedAt":"2024-10-27T23:45:25Z","isPatch":true,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"On Sun, Oct 27, 2024 at 11:07:07PM +0100, Bence Ferdinandy wrote:\n>\n> On Fri Oct 25, 2024 at 08:24, Jeff King <peff@peff.net> wrote:\n> > On Thu, Oct 24, 2024 at 08:48:29PM +0200, Bence Ferdinandy wrote:\n> >\n> >> > So I think rather than \"branch --show-current-remote\", we'd want\n> >> > some option to make \"branch --list\" show only the currently checked out\n> >> > branch, and then you could apply --format to it to get whatever\n> >> > information you wanted. Something like:\n> >> >\n> >> >   git branch --list --is-head --format='%(upstream:remotename)'\n> >>\n> >> Thanks for running through this in such detail! This would be more widely\n> >> useful for sure.\n> >>\n> >> I'd probably call the flag something like \"--current\", \"--current-only\" rather\n> >> than \"--is-head\" though. \"--is-head\" sounds as if it would filter --list but\n> >> not necessarily end up with a single entry.\n> >\n> > Yeah, I think --current would be fine.\n>\n> I was looking through git branch and there is a --show-current option. I was\n> wondering, would it not be better to teach --show-current to also obey\n> --format? It would avoid having a \"--current\" that only works with \"--list\"\n> besides having a \"--show-current\".\n\nYeah, I think that supporting '--format' specifiers via 'git branch\n--show-current' makes sense.\n\nIn the interim you could do something gross like:\n\n    git branch --list --format='%(upstream:remotename)' \\\n      --end-of-options \"$(git branch --show-current)\"\n\n, but... yuck :-).\n\nI think the right thing to do would be to teach 'git branch\n--show-current' to support the full range of --format specifiers. And I\nthink the way to do that would be to treat --show-current as a special\ncase of --list.\n\nIn the existing implementation, we special-case handling the current\nbranch with --show-current via a separate code path in\nbuiltin/branch.c::show_current_branch_name().\n\nIt would be nice to change the implementation there to pretend as if\nthe current branch as the pattern given to --list instead of handling\nprinting it out separately.\n\nI think that would be a nice small-ish project for anybody looking to\nget their hands dirty in the 'branch' builtin's implementation.\n\nThanks,\nTaylor\n"},{"id":"506192","messageId":"20241028053315.GA2827304@coredump.intra.peff.net","threadId":"62379","inReplyTo":"D56XI8GBH2GF.3MP02MGQGP5M@ferdinandy.com","subject":"Re: [RFC PATCH] object-name: add @{upstreamhead} shorthand","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2024-10-28T05:33:15Z","receivedAt":"2024-10-28T05:33:16Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Oct 27, 2024 at 11:07:07PM +0100, Bence Ferdinandy wrote:\n\n> >> I'd probably call the flag something like \"--current\", \"--current-only\" rather\n> >> than \"--is-head\" though. \"--is-head\" sounds as if it would filter --list but\n> >> not necessarily end up with a single entry.\n> >\n> > Yeah, I think --current would be fine.\n> \n> I was looking through git branch and there is a --show-current option. I was\n> wondering, would it not be better to teach --show-current to also obey\n> --format? It would avoid having a \"--current\" that only works with \"--list\"\n> besides having a \"--show-current\".\n\nYeah, that's perfect. I had almost suggested \"--list-head\" originally,\nbut I didn't want to introduce yet another major-mode to git-branch. But\nif we already have it, that's not a problem. :)\n\nAnd the patch should be quite short, I'd think.\n\n-Peff\n"}]}