Git stash on windows extremly slow compared to Libgit2
Asked Answered
U

3

6

Recently I've been using git stash many times and I've been thinking that it is really slow, even on a new repository with a single file. I've read this question about git stash slowness and this other one and tried every answer to these questions but nothing actually works.

For example I've done the following steps to reproduce it:

  1. git init
  2. touch file.txt
  3. vim file.txt (edit the file adding 2 lines)
  4. git add .
  5. git commit -m "Initial commit"
  6. vim file.txt (edit it again adding 1 line)
  7. time git stash

Output:

$ time git stash
Saved working directory and index state WIP on master: b9454ed Initial commit
HEAD is now at b9454ed Initial commit    
real    0m8.042s
user    0m0.000s
sys     0m0.046s

8 seconds for stashing a single line is so much time. Now a test using libgit2sharp:

static void Main(string[] args)
{
    Repository repo=new Repository(@"C:\Users\UserTest\TestGitRepo");

    repo.Stashes.Add(new Signature("test", "[email protected]", new DateTimeOffset(DateTime.Now)), "Stash on master");
}

This code takes 74ms to stash the same change. If Libgit2 is that fast then it should be possible to speed up git stash command. How can I achieve this?

Actually using windows 10 64bit and git 2.11 64bits. Other git commands (like status, add, commit, etc.) work fine.

UPDATE: I've updated to git 2.13 and now it's 14,53s for git stash...

UPDATE 2: I've updated to git 2.15 and trying the same test time git stash returns real 0m6,553s. Still really slow...

Uvulitis answered 24/5, 2017 at 13:30 Comment(11)
Actually, on my computer a sh.exe.stackdump is created, can you verify that git stash actually did what it was supposed to do?Commune
@LasseV.Karlsen it did what is expected. The last line is stashed in both cases using the steps of my question.Uvulitis
Yes, the line is stashed on my end as well, but bash also crashed with a stack overflow. But this does not account for the time taken so just ignore my comments.Commune
Agh, for some reason I had managed to go back to the 64-bit version of git which has problems with stack overflow exceptions in bash. Restored 32-bit and the crash dump went away.Commune
I am using 64 bits git without crashes.Uvulitis
I know. Some people, like me, experience problems with some commands on 64-bit, rebasing and now apparently stashing, have problems. Installing a 32-bit client removes all the problems though.Commune
Numerous Git commands are written as shell scripts. On Linux and Unix systems these run in perfectly reasonable time. On Windows, apparently (I don't use Windows so I have not experienced this), they run excruciatingly slowly. As a result, the Git folks have been rewriting more and more Git commands to avoid the use of shell scripts. I wonder if it might be more profitable to fix whatever is causing the shell to be so slow, but perhaps that's something fundamental to Windows.Godfearing
Can be improved the performance of these scripts? It's too much time for a single line to wait 8 secs...Uvulitis
You could check this question for recipes though I should say I do not remember any tweak helped me noticeably.Arnettaarnette
I've tried them but still the same :sUvulitis
See github.com/msysgit/git/issues/259. It's dated but was closed (msysgit).Berwickupontweed
U
3

Since Git 2.22

Since Git 2.22 the previously experimental feature is now stable and the default option.

Below Git 2.22

One year later, installing Git 2.19 I've seen a checkbox during git installation to enable the new experimental built-in stash.

Experimental built-in git stash

In my case it works fine and I've noticed a huge performance improvement compared to the old implementation (which was using a script) and it's actually as fast as using the same command in linux.

Here the results following exactly the same steps:

$ time git stash
Saved working directory and index state WIP on master: 7a29b92 Initial commit

real    0m0,120s
user    0m0,000s
sys     0m0,015s
Uvulitis answered 6/10, 2018 at 12:36 Comment(0)
K
1

To add to the existing answer you can enable the new feature if you’ve already installed 2.19 or later with:

git config --global stash.usebuiltin true

This works with the portable edition as well.

Please note that this feature doesn’t seem to work with submodules yet. https://github.com/git-for-windows/git/issues/1820

Kruter answered 10/10, 2018 at 18:28 Comment(1)
Looks like they closed off that bug not long after your answer!Eisenhower
T
1

git stash will be faster with Git 2.25 (Q1 2020), where users of oneway_merge() (like "reset --hard") learned to take advantage of fsmonitor to avoid unnecessary lstat(2) calls.

(Since Git 2.22, Q2 2019, git stash is entirely rewritten in C, and is the default)

See commit 679f2f9 (20 Nov 2019) by Utsav Shah (Utsav2).
(Merged by Junio C Hamano -- gitster -- in commit 473b431, 05 Dec 2019)

unpack-trees: skip stat on fsmonitor-valid files

Helped-by: Junio C Hamano
Helped-by: Kevin Willford
Signed-off-by: Utsav Shah

The index might be aware that a file hasn't modified via fsmonitor, but unpack-trees did not pay attention to it and checked via ie_match_stat which can be inefficient on certain filesystems.
This significantly slows down commands that run oneway_merge, like checkout and git reset --hard.

This patch makes oneway_merge check whether a file is considered unchanged through fsmonitor and skips ie_match_stat on it.
unpack-trees also now correctly copies over fsmonitor validity state from the source index.
Finally, for correctness, we force a refresh of fsmonitor state in tweak_fsmonitor.

After this change, commands like stash (that use git reset --hard internally) go from 8s or more to ~2s on a 250k file repository on a mac.

Threadfin answered 15/12, 2019 at 18:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.