5

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?

Gordon Fontenot
  • 1,370
  • 3
  • 17
  • 38
  • 1
    So 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 Answers2

1

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 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.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
1
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.

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141