Gordon Fontenot
Gordon Fontenot

Reputation: 1380

Fastest way to figure out if a git repo has unpulled changes for scripting?

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?

Upvotes: 5

Views: 1703

Answers (2)

VonC
VonC

Reputation: 1328712

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 [email protected] 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 in send_ref callbacks

Helped-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 two write(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.

Upvotes: 1

Adam Dymitruk
Adam Dymitruk

Reputation: 129744

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.

Upvotes: 1

Related Questions