{"thread":{"id":"57616","subject":"Runtime performance of git-prompt.sh with verbose upstream summary","startedAt":"2022-03-25T14:26:11Z","lastAt":"2022-03-25T14:26:11Z","messageCount":1,"participants":["Mikko Rantalainen"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"452265","messageId":"7ce7bd47-7ac2-ad57-118a-67e547cffab0@peda.net","threadId":"57616","inReplyTo":null,"subject":"Runtime performance of git-prompt.sh with verbose upstream summary","fromName":"Mikko Rantalainen","fromEmail":"mikko.rantalainen@peda.net","sentAt":"2022-03-25T14:17:18Z","receivedAt":"2022-03-25T14:26:11Z","isPatch":false,"sender":{"key":"mikko.rantalainen@peda.net","avatar":"https://gravatar.com/avatar/e2d770957fa98e434c238272a8ee24c02ab5766ad140c18b9591045c0a49be58?d=mp&s=160"},"body":"Hi!\n\nI have configured my bash prompt to automatically have git summary in my\nprompt like this in ~/.bashrc\n\nif [ \"$color_prompt\" = yes ]; then\n    source /usr/lib/git-core/git-sh-prompt\n    GIT_PS1_SHOWDIRTYSTATE=0\n    GIT_PS1_SHOWSTASHSTATE=0\n    GIT_PS1_SHOWUNTRACKEDFILES=0\n    GIT_PS1_SHOWUPSTREAM=verbose\n\nPS1='\\[\\033[01;32m\\]\\u@\\h\\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]$(__git_ps1\n\" (%s)\")\\$ '\nelse\n...\n\nWhenever I `cd` any directory which is part of a git checkout, my prompt\nshows me summary of commits in the current working directory vs\nrespective upstream. This is exactly what I want but I noticed that if I\nhave a big project with an old branch checked out, the computation to\nfigure out the total amount of commits gets so expensive that doing it\nfor every shell prompt gets too slow to be usable. So the behavior is\ncorrect but too slow in practice.\n\nA specific example I can publicly share was one checkout where my local\n\"master\" branch of linux kernel was at\n72bc15d0018ebfbc9c389539d636e2e9a9002b3b and origin/master was at\nd4899e5542c15062cc55cac0ca99025bb64edc61. Computing the amount of\nchanges took multiple seconds and the shell prompt hangs for the whole\ntime, obviously.\n\nLooking at the actual code, it appears that the git-sh-prompt runs\n\n    git rev-list --left-right \"$upstream\"...HEAD\n\nat line\n\nhttps://github.com/git/git/blob/5c0cbdb107c5e1c1474618535fda438f25d260ca/contrib/completion/git-prompt.sh#L187\n\nto actually compute the summary. How about changing that to\n\n    timeout 1 git rev-list --left-right \"$upstream\"...HEAD\n\ninstead? (Or maybe even smaller timeout?)\n\nThat would avoid blocking the shell prompt for longer than 1 second even\nif this computation would take a lot of time. And in case timeout is\nexceeded, the verbose upstream information will be just missing and the\nprompt will work just fine otherwise. Or maybe the verbose upstream\nsummary could be replaced with \"??\" in case timeout was exceeded?\n\nAn even better implementation could have very short timeout for\ncomputing the prompt (e.g. 100 ms) and if the timeout is exceeded, the\ncomputing would be executed once in the background and cached somewhere\nto be displayed on the prompt automatically. If that cache were put into\na file, it's modification time could be checked against .git/HEAD to\nfigure out if the HEAD has been changed since the cache was last computed.\n\nThe prompt could even show something like\n\n   user@example.com:~/src/linux (master $ u+1475??)$\n\nif the verbose detail \"u+5123\" was displayed from stale cache so that\nthe prompt would still show the last known value but the extra question\nmarks indicate that the value may not be correct.\n\n-- \nMikko\n"}]}