{"thread":{"id":"62896","subject":"Usability issue: \"Your branch is up to date\"","startedAt":"2025-02-03T16:45:50Z","lastAt":"2025-02-07T08:20:39Z","messageCount":14,"participants":["Manuel Quiñones","Junio C Hamano","Bram van Oosterhout","D. Ben Knoble","Patrick Steinhardt","Karthik Nayak"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"511746","messageId":"CAPpV+OaMcViVKok5U0-4HaYyPMKEA7BBzw4t113uAaMndjs5Cg@mail.gmail.com","threadId":"62896","inReplyTo":null,"subject":"Usability issue: \"Your branch is up to date\"","fromName":"Manuel Quiñones","fromEmail":"manuel.por.aca@gmail.com","sentAt":"2025-02-03T16:45:36Z","receivedAt":"2025-02-03T16:45:50Z","isPatch":false,"sender":{"key":"manuel.por.aca@gmail.com","avatar":"https://gravatar.com/avatar/663ad591ba13740abc8e80a08f4da7c9730369495d7f05ccea98bf4287d72636?d=mp&s=160"},"body":"Hi,\nI've been teaching Git to a group of young learners lately. They find\nit odd that commands like `git status` or `git switch main` say \"Your\nbranch is up to date with 'origin/main'\" even when there are changes\nthat can be fetched from the remote. My proposal: Add the timestamp of\nthe last fetch to the message. For example:\n\n```\n$ git switch main\nSwitched to branch 'main'\nYour branch is up to date with 'origin/main'. Last check was 2 hours ago.\n```\n\nIt looks like the timestamp of file `.git/FETCH_HEAD` would be enough\nto implement it.\n\n\n-- \n.. manuq ..\n"},{"id":"511748","messageId":"xmqqh65b2ci3.fsf@gitster.g","threadId":"62896","inReplyTo":"CAPpV+OaMcViVKok5U0-4HaYyPMKEA7BBzw4t113uAaMndjs5Cg@mail.gmail.com","subject":"Re: Usability issue: \"Your branch is up to date\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-02-03T16:56:20Z","receivedAt":"2025-02-03T16:56:23Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Manuel Quiñones <manuel.por.aca@gmail.com> writes:\n\n> that can be fetched from the remote. My proposal: Add the timestamp of\n> the last fetch to the message. For example:\n>\n> ```\n> $ git switch main\n> Switched to branch 'main'\n> Your branch is up to date with 'origin/main'. Last check was 2 hours ago.\n> ```\n>\n> It looks like the timestamp of file `.git/FETCH_HEAD` would be enough\n> to implement it.\n\nNot generally.  Your last fetch may not have been about origin/main\n(e.g., \"git fetch origin next\"), or it may even have been about a\ntotally different remote (e.g., \"git fetch elsewhere\").\n\nThe timestamp of the last entry of the reflog of origin/main may be\na lot better place to look for the information, if available.\n"},{"id":"511768","messageId":"xmqq34guzi0f.fsf@gitster.g","threadId":"62896","inReplyTo":"xmqqh65b2ci3.fsf@gitster.g","subject":"Re: Usability issue: \"Your branch is up to date\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-02-04T00:10:56Z","receivedAt":"2025-02-04T00:10:58Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Manuel Quiñones <manuel.por.aca@gmail.com> writes:\n>\n>> that can be fetched from the remote. My proposal: Add the timestamp of\n>> the last fetch to the message. For example:\n>>\n>> ```\n>> $ git switch main\n>> Switched to branch 'main'\n>> Your branch is up to date with 'origin/main'. Last check was 2 hours ago.\n>> ```\n>>\n>> It looks like the timestamp of file `.git/FETCH_HEAD` would be enough\n>> to implement it.\n>\n> Not generally.  Your last fetch may not have been about origin/main\n> (e.g., \"git fetch origin next\"), or it may even have been about a\n> totally different remote (e.g., \"git fetch elsewhere\").\n>\n> The timestamp of the last entry of the reflog of origin/main may be\n> a lot better place to look for the information, if available.\n\nUnfortunately, this is not quite enough.\n\nI do not think a \"git fetch\" that noticed that the remote-tracking\nbranch is up-to-date updates the reflog of the remote-tracking\nbranch, so if you observed that their 'main' is at certain value 10\nhours ago, and if your more recent fetch done two hours ago found\nthat they haven't made any progress, the reflog says \"You observed\nthat their 'main' is at this commit as of 10 hours ago\" and not the\nnumber you want.\n\nHowever, as I said, the fetch that touched the FETCH_HEAD file may\nnot have been about the ref in question, so while a two-hour old\nFETCH_HEAD can guarantee that update of any ref by fetching\n(including a fetch done as part of \"git pull\") did not happen in the\nlast two hours, it does not really mean what you have in your\nremote-tracking branch is not stale from reality by more than two\nhours.\n\nYou could inspect the contents of FETCH_HEAD to see if the source of\nthe remote-tracking branch is listed there, and when it appears in\nthe file, can use the timestamp of the file.  If you did this:\n\n    $ git fetch origin main\n\nand it left something like\n\n\tf93ff170b... branch 'main' of https://www.kernel.org/...\n\nin the file, you can reverse map the URL and the branch using the\nremote.*.URL and the remote.*.fetch configuration variables to\nfigure out that it must have been stored at our 'origin/main'.\nAt that point, you know that the timestamp of FETCH_HEAD would be\nwhen we observed that value in the 'origin/main'.\n\nBut even then, because the FETCH_HEAD file is not versioned, if you\ndid\n\n    $ git fetch elsewhere main\n\nthen the file gets overwritten, and you would no longer know when\nwas the last time you observed the value of 'origin/main'.\n\nIn short, there is not enough information kept anywhere to compute\nthe number you want to show reliably.\n"},{"id":"511770","messageId":"CAMoUM6+9SHybvWVp3SKDD4RWesruh=nmMacXn_oL893CPCn39g@mail.gmail.com","threadId":"62896","inReplyTo":"xmqq34guzi0f.fsf@gitster.g","subject":"Re: Usability issue: \"Your branch is up to date\"","fromName":"Bram van Oosterhout","fromEmail":"adriaanbram0712@gmail.com","sentAt":"2025-02-04T00:28:26Z","receivedAt":"2025-02-04T00:28:39Z","isPatch":false,"sender":{"key":"adriaanbram0712@gmail.com","avatar":null},"body":"Ahhhh, this thread explains my confusion when, even though git locally\ntells me my branch is \"up to date\", a fetch demonstrates the branch is\nnot up to date.\n\nWhich begs the question: Why does git say: \"Your branch is up to date\n...\" if at best it can say: \"Your\nbranch MIGHT BE up to date with ...\"?\n\nI have learned not to rely on the message and come to expect\n(sometimes nasty) surprises when I return to a project after a few\nmonths,\n\nBram\n\nOn Tue, Feb 4, 2025 at 11:11 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n> > Manuel Quiñones <manuel.por.aca@gmail.com> writes:\n> >\n> >> that can be fetched from the remote. My proposal: Add the timestamp of\n> >> the last fetch to the message. For example:\n> >>\n> >> ```\n> >> $ git switch main\n> >> Switched to branch 'main'\n> >> Your branch is up to date with 'origin/main'. Last check was 2 hours ago.\n> >> ```\n> >>\n> >> It looks like the timestamp of file `.git/FETCH_HEAD` would be enough\n> >> to implement it.\n> >\n> > Not generally.  Your last fetch may not have been about origin/main\n> > (e.g., \"git fetch origin next\"), or it may even have been about a\n> > totally different remote (e.g., \"git fetch elsewhere\").\n> >\n> > The timestamp of the last entry of the reflog of origin/main may be\n> > a lot better place to look for the information, if available.\n>\n> Unfortunately, this is not quite enough.\n>\n> I do not think a \"git fetch\" that noticed that the remote-tracking\n> branch is up-to-date updates the reflog of the remote-tracking\n> branch, so if you observed that their 'main' is at certain value 10\n> hours ago, and if your more recent fetch done two hours ago found\n> that they haven't made any progress, the reflog says \"You observed\n> that their 'main' is at this commit as of 10 hours ago\" and not the\n> number you want.\n>\n> However, as I said, the fetch that touched the FETCH_HEAD file may\n> not have been about the ref in question, so while a two-hour old\n> FETCH_HEAD can guarantee that update of any ref by fetching\n> (including a fetch done as part of \"git pull\") did not happen in the\n> last two hours, it does not really mean what you have in your\n> remote-tracking branch is not stale from reality by more than two\n> hours.\n>\n> You could inspect the contents of FETCH_HEAD to see if the source of\n> the remote-tracking branch is listed there, and when it appears in\n> the file, can use the timestamp of the file.  If you did this:\n>\n>     $ git fetch origin main\n>\n> and it left something like\n>\n>         f93ff170b... branch 'main' of https://www.kernel.org/...\n>\n> in the file, you can reverse map the URL and the branch using the\n> remote.*.URL and the remote.*.fetch configuration variables to\n> figure out that it must have been stored at our 'origin/main'.\n> At that point, you know that the timestamp of FETCH_HEAD would be\n> when we observed that value in the 'origin/main'.\n>\n> But even then, because the FETCH_HEAD file is not versioned, if you\n> did\n>\n>     $ git fetch elsewhere main\n>\n> then the file gets overwritten, and you would no longer know when\n> was the last time you observed the value of 'origin/main'.\n>\n> In short, there is not enough information kept anywhere to compute\n> the number you want to show reliably.\n>\n"},{"id":"511772","messageId":"CAMoUM6Kfa4eoK7bvYRgSN4KWh8XRqE2itjM7wDgJ0AZY75KSfQ@mail.gmail.com","threadId":"62896","inReplyTo":"CAMoUM6LstYx3PJcx-Sz3Dfs-1BxF1uP373MO8+eknbO7j-S01Q@mail.gmail.com","subject":"Fwd: Usability issue: \"Your branch is up to date\"","fromName":"Bram van Oosterhout","fromEmail":"adriaanbram0712@gmail.com","sentAt":"2025-02-04T00:51:04Z","receivedAt":"2025-02-04T00:51:17Z","isPatch":false,"sender":{"key":"adriaanbram0712@gmail.com","avatar":null},"body":"---------- Forwarded message ---------\nFrom: Bram van Oosterhout <adriaanbram0712@gmail.com>\nDate: Tue, Feb 4, 2025 at 11:47 AM\nSubject: Re: Usability issue: \"Your branch is up to date\"\nTo: Chris Torek <chris.torek@gmail.com>\n\n\nOn Tue, Feb 4, 2025 at 11:32 AM Chris Torek <chris.torek@gmail.com> wrote:\n>\n> On Mon, Feb 3, 2025 at 4:28 PM Bram van Oosterhout\n> <adriaanbram0712@gmail.com> wrote:\n> > Ahhhh, this thread explains my confusion when, even though git locally\n> > tells me my branch is \"up to date\", a fetch demonstrates the branch is\n> > not up to date.\n> >\n> > Which begs the question: Why does git say: \"Your branch is up to date\n> > ...\" if at best it can say: \"Your\n> > branch MIGHT BE up to date with ...\"?\n>\n\n(resend: I perpetuated the reply/reply all mistake)\n> Perhaps a small wording change is in order, to say \"your branch is\n> up to date as of the most recent information I have from git fetch\".\n\nOr perhaps: \"Your local branch is unchanged since your last fetch from ...\".\nThat says that I have not made any changes since I last fetched the\nbranch and suggests there could be changes in the remote branch.\n\nBram\n"},{"id":"511774","messageId":"CALnO6CB2TjwRWr0=c2nWY5DnwLeqXiaA5fCiEeF85zivmLggjA@mail.gmail.com","threadId":"62896","inReplyTo":"CAMoUM6+9SHybvWVp3SKDD4RWesruh=nmMacXn_oL893CPCn39g@mail.gmail.com","subject":"Re: Usability issue: \"Your branch is up to date\"","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2025-02-04T02:08:12Z","receivedAt":"2025-02-04T02:08:25Z","isPatch":false,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"On Mon, Feb 3, 2025 at 7:28 PM Bram van Oosterhout\n<adriaanbram0712@gmail.com> wrote:\n>\n> Ahhhh, this thread explains my confusion when, even though git locally\n> tells me my branch is \"up to date\", a fetch demonstrates the branch is\n> not up to date.\n>\n> Which begs the question: Why does git say: \"Your branch is up to date\n> ...\" if at best it can say: \"Your\n> branch MIGHT BE up to date with ...\"?\n\n\nWell, the branch _is_ up to date with your remote-tracking branch [1]\norigin/main; that doesn't mean the tracking branch is up-to-date with\nthe repository origin's branch main!\n\nI find it helpful to break the notion for newcomers early on that\norigin/main somehow is \"equal to\" the repository named by origin's\nmain branch. Git (mostly) only communicates with remote repos when you\nfetch, push, or, pull—in other words (and this bit may be more for\nManuel), try to reinforce that things Git knows locally are only local\nand not inherently tied to other repositories. Learning this\ndistributed lesson proves hard in my experience but explains a lot\nabout the reality of how Git operates.\n\nExceptions to the \"remote communication\" rule I can think of that\nprobably don't need to clutter things for beginners:\n- git-maintenance has pre-fetching as a default task\n- git ls-remote lists remote refs by communicating with the remote\n\n> I have learned not to rely on the message and come to expect\n> (sometimes nasty) surprises when I return to a project after a few\n> months,\n>\n> Bram\n\nAnd thus `git fetch [--all]` because a part of your typical workflow,\nor something like `git pull --rebase [origin [main]]` before pushing.\n\n[1]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefremotetrackingbrancharemote-trackingbranch\n\n-- \nD. Ben Knoble\n"},{"id":"511800","messageId":"CAPpV+Oaq3d3oNE-V3pnpQRNrGCoZr52uY91QtWYxcu1tgG_QXg@mail.gmail.com","threadId":"62896","inReplyTo":"xmqq34guzi0f.fsf@gitster.g","subject":"Re: Usability issue: \"Your branch is up to date\"","fromName":"Manuel Quiñones","fromEmail":"manuel.por.aca@gmail.com","sentAt":"2025-02-04T12:38:30Z","receivedAt":"2025-02-04T12:38:42Z","isPatch":false,"sender":{"key":"manuel.por.aca@gmail.com","avatar":"https://gravatar.com/avatar/663ad591ba13740abc8e80a08f4da7c9730369495d7f05ccea98bf4287d72636?d=mp&s=160"},"body":"El lun, 3 feb 2025 a la(s) 9:10 p.m., Junio C Hamano\n(gitster@pobox.com) escribió:\n>\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n> > Manuel Quiñones <manuel.por.aca@gmail.com> writes:\n> >\n> >> that can be fetched from the remote. My proposal: Add the timestamp of\n> >> the last fetch to the message. For example:\n> >>\n> >> ```\n> >> $ git switch main\n> >> Switched to branch 'main'\n> >> Your branch is up to date with 'origin/main'. Last check was 2 hours ago.\n> >> ```\n> >>\n> >> It looks like the timestamp of file `.git/FETCH_HEAD` would be enough\n> >> to implement it.\n> >\n> > Not generally.  Your last fetch may not have been about origin/main\n> > (e.g., \"git fetch origin next\"), or it may even have been about a\n> > totally different remote (e.g., \"git fetch elsewhere\").\n> >\n> > The timestamp of the last entry of the reflog of origin/main may be\n> > a lot better place to look for the information, if available.\n>\n> Unfortunately, this is not quite enough.\n>\n> I do not think a \"git fetch\" that noticed that the remote-tracking\n> branch is up-to-date updates the reflog of the remote-tracking\n> branch, so if you observed that their 'main' is at certain value 10\n> hours ago, and if your more recent fetch done two hours ago found\n> that they haven't made any progress, the reflog says \"You observed\n> that their 'main' is at this commit as of 10 hours ago\" and not the\n> number you want.\n>\n> However, as I said, the fetch that touched the FETCH_HEAD file may\n> not have been about the ref in question, so while a two-hour old\n> FETCH_HEAD can guarantee that update of any ref by fetching\n> (including a fetch done as part of \"git pull\") did not happen in the\n> last two hours, it does not really mean what you have in your\n> remote-tracking branch is not stale from reality by more than two\n> hours.\n>\n> You could inspect the contents of FETCH_HEAD to see if the source of\n> the remote-tracking branch is listed there, and when it appears in\n> the file, can use the timestamp of the file.  If you did this:\n>\n>     $ git fetch origin main\n>\n> and it left something like\n>\n>         f93ff170b... branch 'main' of https://www.kernel.org/...\n>\n> in the file, you can reverse map the URL and the branch using the\n> remote.*.URL and the remote.*.fetch configuration variables to\n> figure out that it must have been stored at our 'origin/main'.\n> At that point, you know that the timestamp of FETCH_HEAD would be\n> when we observed that value in the 'origin/main'.\n>\n> But even then, because the FETCH_HEAD file is not versioned, if you\n> did\n>\n>     $ git fetch elsewhere main\n>\n> then the file gets overwritten, and you would no longer know when\n> was the last time you observed the value of 'origin/main'.\n>\n> In short, there is not enough information kept anywhere to compute\n> the number you want to show reliably.\n\nThanks for the insightful explanation Junio! Looking forward, do you\nthink that it could be possible to record the timestamp that the\nremote-tracking branch has been updated with the remote branch? In\norder to make such information available to the end user.\n\n-- \n.. manuq ..\n"},{"id":"511801","messageId":"CAPpV+ObaMU+WQM5gVCcY3ypPaobMtbu3dZQByOKPXyiscUBcuA@mail.gmail.com","threadId":"62896","inReplyTo":"CALnO6CB2TjwRWr0=c2nWY5DnwLeqXiaA5fCiEeF85zivmLggjA@mail.gmail.com","subject":"Re: Usability issue: \"Your branch is up to date\"","fromName":"Manuel Quiñones","fromEmail":"manuel.por.aca@gmail.com","sentAt":"2025-02-04T12:53:13Z","receivedAt":"2025-02-04T12:53:24Z","isPatch":false,"sender":{"key":"manuel.por.aca@gmail.com","avatar":"https://gravatar.com/avatar/663ad591ba13740abc8e80a08f4da7c9730369495d7f05ccea98bf4287d72636?d=mp&s=160"},"body":"El lun, 3 feb 2025 a la(s) 11:08 p.m., D. Ben Knoble\n(ben.knoble@gmail.com) escribió:\n>\n> On Mon, Feb 3, 2025 at 7:28 PM Bram van Oosterhout\n> <adriaanbram0712@gmail.com> wrote:\n> >\n> > Ahhhh, this thread explains my confusion when, even though git locally\n> > tells me my branch is \"up to date\", a fetch demonstrates the branch is\n> > not up to date.\n> >\n> > Which begs the question: Why does git say: \"Your branch is up to date\n> > ...\" if at best it can say: \"Your\n> > branch MIGHT BE up to date with ...\"?\n>\n>\n> Well, the branch _is_ up to date with your remote-tracking branch [1]\n> origin/main; that doesn't mean the tracking branch is up-to-date with\n> the repository origin's branch main!\n>\n> I find it helpful to break the notion for newcomers early on that\n> origin/main somehow is \"equal to\" the repository named by origin's\n> main branch. Git (mostly) only communicates with remote repos when you\n> fetch, push, or, pull—in other words (and this bit may be more for\n> Manuel), try to reinforce that things Git knows locally are only local\n> and not inherently tied to other repositories. Learning this\n> distributed lesson proves hard in my experience but explains a lot\n> about the reality of how Git operates.\n\nThanks for the advice Ben. Very good point. I will introduce the\ndifference between the origin's main branch and the remote-tracking\nbranch early in lessons. This is a core part of how Git works.\n\nStill I suggest improving the usability for new generations with a\ntimestamp of the remote-tracking branch last update. Hopefully in the\nfuture it will be possible!\n\n--\n.. manuq ..\n"},{"id":"511818","messageId":"xmqqseottxld.fsf@gitster.g","threadId":"62896","inReplyTo":"CAPpV+Oaq3d3oNE-V3pnpQRNrGCoZr52uY91QtWYxcu1tgG_QXg@mail.gmail.com","subject":"Re: Usability issue: \"Your branch is up to date\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-02-04T17:43:10Z","receivedAt":"2025-02-04T17:43:12Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Manuel Quiñones <manuel.por.aca@gmail.com> writes:\n\n> Thanks for the insightful explanation Junio! Looking forward, do you\n> think that it could be possible to record the timestamp that the\n> remote-tracking branch has been updated with the remote branch? In\n> order to make such information available to the end user.\n\nThe time at which each remote-tracking branch was updated is already\nrecorded in the reflog.  What is missing is the timestamp that a\nfetch checked if a remote-tracking branch needs updating, found that\nthe branch at the remote hasn't changed, and did not update the\nremote-tracking branch.\n\nYou'd need to first design where to store that information and how.\n\nIt does not have to be in the reflog, but as a thought experiment,\nlet's take how the design would go if we decided to use reflog to\nstore that information.\n\nWhat a reflog entry records, in textual form, looks like\n\n<old-object-name> <new-object-name> <user-ident> <timestamp> <comment>\n\nWe can imagine adding a new reflog entry whenever \"git fetch\" finds\nthat the branch at the remote hasn't been updated, with the same\nvalue in <old-object-name> and <new-object-name>.\n\nA reflog file I randomly picked as a sample is ~5k long with 34\nentries (it keeps track of my fetching from and pushing to\nhttps://git.kernel.org/pub/scm/git/git.git/#master), so a reflog\ncosts around 150 bytes per entry, and if you fetch once every hour\nthat would be like ~3k per branch per day.\n\nWhile that is a trivial and insignificant number from storage cost\npoint of view, if you are monitoring the progress of the remote with\n\"git reflog origin/main\", I suspect that such a change would make it\nunusably noisy, so \"git reflog\" command may need to grow an option\nthat tells it to skip these no-op entries.\n\nAs to required change to \"git fetch\", this may be a bit tricky.\n\nIIRC (I am writing from the memory without looking at the code),\nwhen you say \"git fetch [<remote> [<refspec>...]]\", what it does\nis roughly to:\n\n - figure out what <remote> and <refspec>... to use from the\n   configuration, if omitted on the command line.\n\n - connect to the remote, and ask the current value of their refs.\n\n - drop any refspec <src>:<dst> whose <dst> side already has the\n   value the remote has.\n\n - drive the object transfer machinery to receive the pack data from\n   the remote and store it locally.\n\n - update the remote-tracking branches.\n\nAnd the last step is where the remote-tracking branches are updated,\ntogether with their reflog (if enabled).  Because that step does not\neven see the remote-tracking branches whose value do not need to\nchange (filtered out earlier to help reduce the number of refs fed\nto the object transfer machinery), the \"drop no-op early\" part need\nto be designed differently (e.g. mark them as no-op, so that the \nobject tranfer machinery can notice them and ignore) and then the\n\"update refs\" step can see these no-op updates.\n\nI do not think writing the \"no-op\" reflog entries should be done at\na step separate from the step that writes the real ref updates, as I\nsuspect that such a separate update scheme would have a funny\ninteractions with \"git fetch --atomic\".\n\nSo, do I think it could be possible?  Sure.  Do I think it would be\ntoo hard as a rocket surgery?  No.  Will I jump up and down excited\nand start coding?  I am not interested all that much, but I can help\nreviewing patches if somebody else works on it.\n\nThere may be some other downsides (other than the cost of storage\nand making the reflog noisy) I haven't thought about, which need to\nbe considered if somebody decides to work on this.\n\nThanks.\n\n\n"},{"id":"511847","messageId":"CAMoUM6JfUGM2RGS_QtTS2XLF89iTt9L-8oOz6h4oWFMc+QMcDg@mail.gmail.com","threadId":"62896","inReplyTo":"CALnO6CB2TjwRWr0=c2nWY5DnwLeqXiaA5fCiEeF85zivmLggjA@mail.gmail.com","subject":"Re: Usability issue: \"Your branch is up to date\"","fromName":"Bram van Oosterhout","fromEmail":"adriaanbram0712@gmail.com","sentAt":"2025-02-05T03:55:15Z","receivedAt":"2025-02-05T03:55:28Z","isPatch":false,"sender":{"key":"adriaanbram0712@gmail.com","avatar":null},"body":"On Tue, Feb 4, 2025 at 1:08 PM D. Ben Knoble <ben.knoble@gmail.com> wrote:\n>\n> On Mon, Feb 3, 2025 at 7:28 PM Bram van Oosterhout\n> <adriaanbram0712@gmail.com> wrote:\n> >\n> > Ahhhh, this thread explains my confusion when, even though git locally\n> > tells me my branch is \"up to date\", a fetch demonstrates the branch is\n> > not up to date.\n> >\n> > Which begs the question: Why does git say: \"Your branch is up to date\n> > ...\" if at best it can say: \"Your\n> > branch MIGHT BE up to date with ...\"?\n>\n>\n> Well, the branch _is_ up to date with your remote-tracking branch [1]\n> origin/main; that doesn't mean the tracking branch is up-to-date with\n> the repository origin's branch main!\n>\n> I find it helpful to break the notion for newcomers early on that\n> origin/main somehow is \"equal to\" the repository named by origin's\n> main branch. Git (mostly) only communicates with remote repos when you\n> fetch, push, or, pull—in other words (and this bit may be more for\n> Manuel), try to reinforce that things Git knows locally are only local\n> and not inherently tied to other repositories. Learning this\n> distributed lesson proves hard in my experience but explains a lot\n> about the reality of how Git operates.\n>\n> Exceptions to the \"remote communication\" rule I can think of that\n> probably don't need to clutter things for beginners:\n> - git-maintenance has pre-fetching as a default task\n> - git ls-remote lists remote refs by communicating with the remote\n>\n> > I have learned not to rely on the message and come to expect\n> > (sometimes nasty) surprises when I return to a project after a few\n> > months,\n> >\n> > Bram\n>\n> And thus `git fetch [--all]` because a part of your typical workflow,\n> or something like `git pull --rebase [origin [main]]` before pushing.\n\nThanks all for the education.\n\nI have always read the message \"Your branch is up to date with\n'origin/main'.\" as\n\"Your branch is up to date with _main_ at _origin_\", with _origin_\nbeing the remote repo.\n\nI now understand it says:\nYour branch is up to date _according to_ the information available at\n.git/refs/remotes/origin/main.\nSince that is a local file , I can reasonably expect the info to be\nstale when I return to my repo after 6 months and I should do a git\nfetch to assess the situation\n\nThanks again. Bram\n>\n> [1]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefremotetrackingbrancharemote-trackingbranch\n>\n> --\n> D. Ben Knoble\n"},{"id":"511852","messageId":"Z6MLOA3mJGbPFBae@pks.im","threadId":"62896","inReplyTo":"xmqqseottxld.fsf@gitster.g","subject":"Re: Usability issue: \"Your branch is up to date\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-02-05T06:54:48Z","receivedAt":"2025-02-05T06:54:58Z","isPatch":false,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Feb 04, 2025 at 09:43:10AM -0800, Junio C Hamano wrote:\n> And the last step is where the remote-tracking branches are updated,\n> together with their reflog (if enabled).  Because that step does not\n> even see the remote-tracking branches whose value do not need to\n> change (filtered out earlier to help reduce the number of refs fed\n> to the object transfer machinery), the \"drop no-op early\" part need\n> to be designed differently (e.g. mark them as no-op, so that the \n> object tranfer machinery can notice them and ignore) and then the\n> \"update refs\" step can see these no-op updates.\n> \n> I do not think writing the \"no-op\" reflog entries should be done at\n> a step separate from the step that writes the real ref updates, as I\n> suspect that such a separate update scheme would have a funny\n> interactions with \"git fetch --atomic\".\n> \n> So, do I think it could be possible?  Sure.  Do I think it would be\n> too hard as a rocket surgery?  No.  Will I jump up and down excited\n> and start coding?  I am not interested all that much, but I can help\n> reviewing patches if somebody else works on it.\n> \n> There may be some other downsides (other than the cost of storage\n> and making the reflog noisy) I haven't thought about, which need to\n> be considered if somebody decides to work on this.\n\nOne thing to consider is that some remotes tend to have many thousands\nor even hundreds of thousands of references. Updating timestamps for all\nof them could be quite inefficient depending on where exactly that data\nis store. If it was in the form of no-op reflog entries, the \"files\"\nbackend would have to touch as many files as the remote has references.\nConsequently, even if only a single remote ref changed, we'd potentially\nhave to update metadata on hundreds of thousands of files.\n\nSo I'm not sure whether such a schema would scale well enough in the\ngeneral case for large repos.\n\nPatrick\n"},{"id":"511897","messageId":"xmqqikponsk6.fsf@gitster.g","threadId":"62896","inReplyTo":"Z6MLOA3mJGbPFBae@pks.im","subject":"Re: Usability issue: \"Your branch is up to date\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-02-05T18:40:41Z","receivedAt":"2025-02-05T18:40:44Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> One thing to consider is that some remotes tend to have many thousands\n> or even hundreds of thousands of references. Updating timestamps for all\n> of them could be quite inefficient depending on where exactly that data\n> is store. If it was in the form of no-op reflog entries, the \"files\"\n> backend would have to touch as many files as the remote has references.\n> Consequently, even if only a single remote ref changed, we'd potentially\n> have to update metadata on hundreds of thousands of files.\n>\n> So I'm not sure whether such a schema would scale well enough in the\n> general case for large repos.\n\nI actually view that as quite an orthogonal issue.\n\nRecording the fact that you checked the state of thousands of refs\nat the remote and found them unchanged is probably a very small part\nof a larger problem that checking the state of thousands of refs is\nalready expensive.  People have solved it at the protocol level to\nlimit the ref advertisement to only the relevant refs (as opposed to\nthe original protocol where the server end unconditionally\nadvertises the state of all of its refs at the beginning of the\nconversation), so when you are only pulling a single branch from\nthere, you do not even observe the state of other unrelated refs\n(like other branches or pull/*/ hierarchy), hence you would not\ncreate these no-op reflog entries.\n\nIf the user, on the other hand, is interested in keeping track of\nall these thousands of refs, \"git fetch\" would have to ask and\nreceive advertisement for all these thousands of refs anyway, and\nat that point, recording the no-op update would be a very small\npart of the problem, I suspect.  Besides, we have reftable that\nwould make this kind of problem easier to solve, no? ;-)\n\n\n\n\n\n\n"},{"id":"511989","messageId":"Z6SGjSik-rRsAGUU@pks.im","threadId":"62896","inReplyTo":"xmqqikponsk6.fsf@gitster.g","subject":"Re: Usability issue: \"Your branch is up to date\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-02-06T09:53:17Z","receivedAt":"2025-02-06T09:53:22Z","isPatch":false,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Wed, Feb 05, 2025 at 10:40:41AM -0800, Junio C Hamano wrote:\n> If the user, on the other hand, is interested in keeping track of\n> all these thousands of refs, \"git fetch\" would have to ask and\n> receive advertisement for all these thousands of refs anyway, and\n> at that point, recording the no-op update would be a very small\n> part of the problem, I suspect.  Besides, we have reftable that\n> would make this kind of problem easier to solve, no? ;-)\n\nYeah, I was pondering whether to bring up reftables or not :) But\nindeed, with them it would be way more efficient, at least assuming that\nwe write everything in a single transaction and not via multiple\ntransactions. Which we generally don't in git-fetch(1) unless the user\nasks for `--atomic` because we allow for a subset of the updates to\nfail. Consequently, even with reftables we'd end up writing N separate\nupdates, where N is the number of advertised refs.\n\nThis is a known problem that we actually plan to fix. Karthik is working\non support for \"partial\" transactions, where it is allowed that a subset\nof ref updates fails without impacting other refs where the update would\nsucceed. With this in place we could then refactor git-fetch(1) to write\nthe update with a single transaction, only, even in the non-atomic case.\n\nPatrick\n"},{"id":"512047","messageId":"CAOLa=ZRz0dFB46y6RtxMuwAdY=u8xh1msp2pscT_4hwUuBk7Dg@mail.gmail.com","threadId":"62896","inReplyTo":"Z6SGjSik-rRsAGUU@pks.im","subject":"Re: Usability issue: \"Your branch is up to date\"","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2025-02-07T08:20:37Z","receivedAt":"2025-02-07T08:20:39Z","isPatch":false,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> On Wed, Feb 05, 2025 at 10:40:41AM -0800, Junio C Hamano wrote:\n>> If the user, on the other hand, is interested in keeping track of\n>> all these thousands of refs, \"git fetch\" would have to ask and\n>> receive advertisement for all these thousands of refs anyway, and\n>> at that point, recording the no-op update would be a very small\n>> part of the problem, I suspect.  Besides, we have reftable that\n>> would make this kind of problem easier to solve, no? ;-)\n>\n> Yeah, I was pondering whether to bring up reftables or not :) But\n> indeed, with them it would be way more efficient, at least assuming that\n> we write everything in a single transaction and not via multiple\n> transactions. Which we generally don't in git-fetch(1) unless the user\n> asks for `--atomic` because we allow for a subset of the updates to\n> fail. Consequently, even with reftables we'd end up writing N separate\n> updates, where N is the number of advertised refs.\n>\n> This is a known problem that we actually plan to fix. Karthik is working\n> on support for \"partial\" transactions, where it is allowed that a subset\n> of ref updates fails without impacting other refs where the update would\n> succeed. With this in place we could then refactor git-fetch(1) to write\n> the update with a single transaction, only, even in the non-atomic case.\n>\n\nYou've played my hand here, I've posted the series now [1] and agree\nwith everything you've said here. It should really help with optimizing\nreftables.\n\n[1]: https://lore.kernel.org/git/20250207-245-partially-atomic-ref-updates-v1-0-e6a3690ff23a@gmail.com/T/#t\n\nThanks\n\n> Patrick\n"}]}