git-up / GitUp

The Git interface you've been missing all your life has finally arrived.
http://gitup.co
GNU General Public License v3.0
11.45k stars 1.24k forks source link

GitUp hangs on almost every action with a repo #942

Open Gray-Wind opened 1 year ago

Gray-Wind commented 1 year ago

Actions like commit, move commits, split commits and many more lead to ~20 hang of the application.

I've looked at spindump and the problem is in snapshots saving:

1000  -[GCLiveRepository _saveSnapshot:withReason:argument:] + 604 (GitUpKit + 100676) [0x101458944]
  1000  -[GCLiveRepository _writeSnapshots] + 132 (GitUpKit + 99316) [0x1014583f4]
    1000  +[NSKeyedArchiver archiveRootObject:toFile:] + 224 (Foundation + 1091320) [0x18c6756f8]
      1000  -[NSKeyedArchiver finishEncoding] + 640 (Foundation + 299560) [0x18c5b4228]

I've found where snapshots are stored and they are way too big. I suppose that's the reason of hangs.

ls -lh .git/co.gitup.mac/snapshots.data
-rw-r--r--  1 user  staff   848M Aug  3 11:11 .git/co.gitup.mac/snapshots.data

Is there any way to make them smaller?

lucasderraugh commented 1 year ago

This is unfortunately a long-standing issue https://github.com/git-up/GitUp/issues/415. Frankly it's not one that I've actually investigated yet.

Does your performance improve if you delete that path (.git/co.gitup.mac/snapshots.data)?

Gray-Wind commented 1 year ago

Surprisingly it does, which is very interesting as the repo I use is rather new on my computer (about 1 month only).

lucasderraugh commented 1 year ago

The snapshots mechanism is effectively how the undo/redo stack works in GitUp. We write up to a limit of I believe 100 past operations. So I wouldn't be surprised if over time you eventually get a slowdown when we are persisting up to 100 snapshots.

I know you said that you've only had this repo on your computer for a month, but is it a large repo that was cloned from elsewhere?

As for things that we could try to remedy the situation is have a configurable max number of snapshots to persist. Then you can still have the undo/redo benefits but with a smaller history. Any other solution would involve writing individual snapshots out rather than a single binary blob (most likely alternative), or having the write occur on a background thread (more difficult), but both of these options have a number of implications.

I'd be interested to see if in a week or so you experience the same problem.

Gray-Wind commented 1 year ago

Thank you for the explanation, yes, the repo is rather big, it was cloned directly from the server, but it has a lot of branches and tags.

I will get back in a week or so.

Gray-Wind commented 11 months ago

As we agreed, I am returning back with results. Delays on actions were gradually increasing during the week, so far the size of snapshots is about 500GB.

Gray-Wind commented 11 months ago

I've looked into the data and most of the plist contains references to tags:

image
lucasderraugh commented 11 months ago

500GB or MB? I certainly hope MB 😅. I think as an easy stopgap we could add a customization on the limit for snapshots, effectively limiting your undo stack. Otherwise I think it's a rework of the snapshot mechanism that frankly I don't have the time to maintain.

I think customizing the limit would allow you to use most of GitUp with easy. Out of curiosity if you browse snapshots (command-S) about how many would you say you have?

Gray-Wind commented 11 months ago

500MB, my bad (:

I have about 60 snapshots now, it is not much.

I have a question tho, why snapshot data contains information about all the tags? Most of them years old.

lucasderraugh commented 11 months ago

Ya, the problem is that the snapshots are exactly that, they are entire snapshots of the repo at a given time. So if you want to go back to the state of the repo yesterday, you can do that, but of course that means we need a way to get you there. Now of course a different approach that would be more efficient space wise is to have a diff of the repo, but I'm not sure of a practical way that can be done with what has been written so far.

If it is indeed tags that are really taking up the space for you, potentially git clone <repositoryUrl> --no-tags or deleting local tags git tag -d $(git tag -l) would improve the performance (though I assume you use tags yourself). You can also fetch a limited set of tags, but you have to then be careful as git fetch will pull down all tags at any given time. We could potentially have "limited snapshots" where we don't snapshot everything and allow the snapshots to be essentially sub-snapshots of the repo.

richardtop commented 7 months ago

I'm not using the Snapshots feature at all, is it possible to make a product version without the snapshots, but that's super snappy?

richardtop commented 4 months ago

This really should be the focus, I'm dropping GitUp use solely because of this issue, I cannot use it anymore...

lucasderraugh commented 4 months ago

Well that's no good. Let me take a look this week at offering a preference for amount of history tracking.

richardtop commented 4 months ago

If possible, I'd be happy with zero history tracking, I never use it. In case this significantly improves the performance, this would be a great configuration parameter.

lucasderraugh commented 4 months ago

It's used for the undo stack though, which I assume you do use. @richardtop

richardtop commented 4 months ago

Nope :) image

Cykelero commented 4 months ago

There was a similar bug in Retcon. (which uses GitUpKit under the hood) In that case, at least with the test data I used, disabling persistence of the snapshots was enough to get performance back. (i.e. removing the calls to _writeSnapshots and _readSnapshots)

That makes for a very simple code change, with a good compromise feature-wise. (undo support is intact; and snapshots are discarded on app termination)

Not sure if that issue was the same as this issue, though!

lucasderraugh commented 4 months ago

Interesting, I always thought the snapshots were also used for undo support, but that could also be that I haven't looked deeply enough at the problem.

Cykelero commented 4 months ago

Sorry for the confusion: snapshots are indeed what powers undo/redo, and the methods I mentioned only handle writing/reading their on-disk representation.
Removing the calls makes it so all snapshots are forgotten when you close the repo window (since they are now only in memory) but until that point everything works the same.

lucasderraugh commented 4 months ago

Ah, interesting idea there.