Skip to content
GitLab
    • GitLab: the DevOps platform
    • Explore GitLab
    • Install GitLab
    • How GitLab compares
    • Get started
    • GitLab docs
    • GitLab Learn
  • Pricing
  • Talk to an expert
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
    • Switch to GitLab Next
    Projects Groups Topics Snippets
  • Register
  • Sign in
  • TortoiseGit TortoiseGit
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
    • Locked files
  • Issues 380
    • Issues 380
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 16
    • Merge requests 16
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • TortoiseGitTortoiseGit
  • TortoiseGitTortoiseGit
  • Issues
  • #3708
Closed
Open
Issue created Feb 16, 2021 by shinfd@shinfd

Log window becomes unresponsive when selecting commit with large file list

What steps will reproduce the problem?

  1. Open log window for a repository containing commits that involve many files.
  2. Select (left/right click) the commit with many files changed.
  3. TortoiseGit log window stops responding for extended duration. For >100K files commit, this may even last minutes.
  4. Selecting another smaller commit, and coming back to the large commit results in similar wait.

I have created a test simulation repo containing varying sized commits up to 50K files at https://github.com/shinfd/largerepotest
Note that, due to its simplicity, the wait selecting 50K file commit from this seems to be much shorter than that of the work environment's equivalently sized commit.

What is the expected output? What do you see instead?

Log window resume responding to user input within few seconds.
Getting an equivalent changed file list for a very large commit quickly is possible in CLI git, with commands like git log -m -1 --name-only --oneline COMMIT.

What version of TortoiseGit and Git are you using? On what operating system?

TortoiseGit 2.11.0.0 (C:\Program Files\TortoiseGit\bin)
git version 2.27.0.windows.1 (C:\Program Files\Git\bin; C:\Program Files\Git\mingw64; C:\Program Files\Git\etc\gitconfig)
on Windows 10 x64

Please provide any additional information below.

Such large commits are definitely not something recommended nor commonplace, but can be found in select occasions, such as migration from existing repository, or when changes are imported via automated scripts from other systems. Merging distant branches can also involve large file count. These commit tend to be important, and our integrator was experiencing long delay when touching such commit to do operations like rebasing or tagging.

Using performance profiler, TortoiseGitProc seems to be taking the most time in below 2 places.

  • CListCtrl::GetStringWidth() is called for every column for each file in the changed file list. This function, called from CGitStatusListCtrl::Show() via CResizableColumnsListCtrl::AdjustColumnWidths() to auto-adjust column size, has to calculate width of the rendered string, taking in account the control's font setting. This is very time consuming for a large CListCtrl.
  • LVITEM per each changed file is added to CListCtrl, in CGitStatusListCtrl::AddEntry() called from CGitStatusListCtrl::Show(). Though this is not as costly as the prior, expanding and constructing ListCtrl still becomes very demanding for a extremely large list.

Prior can be mitigated by limiting CListCtrl::GetStringWidth() calls, possibly for visible items only. Latter is harder to address; virtual list (LVS_OWNERDATA) is recommended for handling display of large list in Windows UI, but since CGitStatusListCtrl uses grouping -- which is not available for virtual lists -- this seems to be not viable without heavy modifications.

If virtual list cannot be used, I could suggest to add changed file list display count threshold, as a lightweight workaround. When file count is known to exceed number set in settings, message like "Too many files to display" is shown. I have attached an experimental udiff from REL_2.11.0.0_EXTERNAL to add such change, limiting log window's file list display to a fixed threshold (1000).

toolarge.patch

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking