I want to add a glyph to my prompt if I'm in a git repo that has remote unpulled changes. Right now, I'm trying to check git ls-remote origin -h refs/heads/master
against git rev-parse HEAD
. But that's really slow, and it only shows if the ref differs on the remote and local repos. So if I have unpushed changes, it also returns true. Is there a faster way to check my remote repo to see if I need to pull changes?

- 1,370
- 3
- 17
- 38
-
1So what you're saying is, you want your prompt to hit up a remote server every single time and test if there's changes? That's going to be slow no matter how you code it. – Lily Ballard Jan 09 '12 at 23:41
-
Do you mean to check if your local checkout, supposedly at the head of the local branch, is distinct from the (local) data you have on the remote tracked branch *after* `git fetch` or `remote update` ? Or do you need to poll the distant server live ? – Francois G Jan 09 '12 at 23:49
-
@KevinBallard I know it's going to be slow, and I probably won't end up using it for that reason. – Gordon Fontenot Jan 10 '12 at 00:57
-
@huitseeker I mean is there a simple way to see if the remote has changes that the local does not, preferably without actually fetching. – Gordon Fontenot Jan 10 '12 at 00:58
-
@Gordon I guess what I ask is would you be fine with a solution that would *not* report changes if you have not done [`git remote update`](http://linux.die.net/man/1/git-remote) (or stg analogous, possibly through a periodic polling job) before ? – Francois G Jan 10 '12 at 01:09
-
@huitseeker I would rather do it without doing the `remote update` beforehand. – Gordon Fontenot Jan 10 '12 at 01:29
2 Answers
But that's really slow
Note: if you still favor the git ls-remote
approach, Git 2.1 (Q2 2014) will make the "git rev-parse
" bit of that solution faster, especially on Windows where msysgit has always been quite slow(er):
See commit 745224e by David Turner (dturner-tw
):
refs.c:
SSE2 optimizations for check_refname_component
Optimize
check_refname_component
using SSE2 on x86_64.
git rev-parse HEAD
is a good test-case for this, since it does almost nothing except parse refs.
For one particular repo with about 60k refs, almost all packed, the timings are:Look up table: 29 ms SSE2: 23 ms
This cuts about 20% off of the runtime.
Ondřej Bílka neleai@seznam.cz suggested an SSE2 approach to the substring searches, which netted a speed boost over the SSE4.2 code I had initially written.
With Git 2.34 (Q4 2021) is even faster, reducing number of write(2)
system calls while sending the ref advertisement.
See commit 70afef5, commit 9632839 (01 Sep 2021) by Jacob Vosmaer (jacobvosmaer
).
(Merged by Junio C Hamano -- gitster
-- in commit c2509c5, 20 Sep 2021)
upload-pack
: use stdio insend_ref
callbacksHelped-by: Jeff King
Signed-off-by: Jacob Vosmaer
In both protocol v0 and v2, upload-pack writes one pktline packet per advertised ref to stdout.
That means one or twowrite(2)
syscalls per ref.
This is problematic if these writes become network sends with high overhead.This commit changes both
send_ref
callbacks to use buffered IO using stdio.To give an example of the impact: I set up a single-threaded loop that calls
ls-remote
(with HTTP and protocol v2) on a local GitLab instance, on a repository with 11K refs.
When I switch from Git v2.32.0 to this patch, I see a 40% reduction in CPU time for Git, and 65% for Gitaly (GitLab's Git RPC service).So using buffered IO not only saves syscalls in upload-pack, it also saves time in things that consume upload-pack's output.

- 1,262,500
- 529
- 4,410
- 5,250
git fetch
after that you should see (on the command line or in git status results) if you are behind on commits if you have tracking set up for that branch.
Otherwise, do the ls-remote as you have stated.

- 124,556
- 26
- 146
- 141