Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

worktree.Checkout() causes disk thrashing #758

Open
kunickiaj opened this issue Feb 23, 2018 · 6 comments
Open

worktree.Checkout() causes disk thrashing #758

kunickiaj opened this issue Feb 23, 2018 · 6 comments

Comments

@kunickiaj
Copy link

On macOS 10.13.3 and go 1.10, it seems that calling worktree.Checkout is causing major (GBs) of disk thrashing trying to switch to a branch. Not really sure why.

Anyone else experiencing this same behavior?

@srishanbhattarai
Copy link

Not sure about the disk thrashing, but checking out a branch is tremendously slow for me.

@kunickiaj
Copy link
Author

Any update on this? If i wait long enough checkout happens, but its unusably slow. It's as if its reading every file in the directory tree.

@kunickiaj
Copy link
Author

kunickiaj commented Jan 13, 2019

Still seeing this issue, checking out a branch is unusably slow.
Example: https://github.com/kunickiaj/beer/blob/master/cmd/brew.go#L225

(expected error due to unstaged changes)

time beer brew ABC-123
FATA[0038]                                               error="worktree contains unstaged changes"
beer  9.14s user 7.95s system 44% cpu 38.831 total

(clean tree)

time beer brew ABC-123
beer  27.11s user 24.64s system 46% cpu 1:50.90 total

See attached pprof cpuprofile and svg rendering.
checkout-profile.zip

@kunickiaj
Copy link
Author

running dtrace, to see a little bit more about the fs access that's going on, I noticed that the process is reading every single file in the workdir, even untracked files such as large distribution binaries. Given that my workdir is several GB due to build artifacts, that could explain why it takes so long.

Removing any build artifacts, 2.6GB -> 333MB in my work dir. This resulted in much faster performance. Does it make sense then, to skip files ignored via .gitignore when performing this operation?

beer brew --debug 2.73s user 3.20s system 56% cpu 10.536 total

@meinto
Copy link
Contributor

meinto commented Mar 5, 2019

To consider the .gitignore makes sense.

After a little debugging i found that merkletrie.DiffTree in diffStagingWithWorktree is the long running method:

https://github.com/src-d/go-git/blob/master/worktree.go#L409
https://github.com/src-d/go-git/blob/master/utils/merkletrie/difftree.go#L264

@kunickiaj
Copy link
Author

Yep, that's visible in the profile results I attached previously. Even respecting .gitignore it was a bit slow, but usable at least.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants