Version Control: exception when switching branches

hello there,

as I don’t know where to start, I’ll start chronologically ¯_(ツ)_/¯

some months time ago
we didn’t use Octopus’ Version Control feature at all, but did some POCs resulting in activating said feature throughout all of our applications we deploy with Octopus.

we also decided to use the very same git repository of our actual application to store all *.ocl files, as this worked well for all smaller applications of ours.
changes to version controlled processes and variables and such have also been made on our main branch develop.

this even worked for our dusty old monolith - but resulted in very poor performance in Octopus (more on that later).

some weeks ago
It was time to dust off our monolith, and with the help of this new Version Control feature I was starting with the very first feature/foo branch to overhaul the deployment of our monolith.
changes on process and other version controlled entities in feature/foo are (to this very date) still possible - except for project variables (more an that later aswell).

present day
I need to change a project variable of said monolith but octopus won’t let me change back to my beloved develop branch :frowning:

Version Control settings are fine though:

so when I navigate to project variables in feature/foo, I get a more talky error message:


failed to make directory 'C:/Octopus/Git/FH636WGSP3YMDWB6KSWUP7TLLGAGOQDD/root/worktrees/bAICHQ3PZZY4XMROOMR2BJXAWEI3DTADW': directory exists

(this google search was not helping my current mental health either :D)

anyway, we found out that firstly yes, this directory does indeed exist on our octopus server, and secondly that for some reason the complete content of our dusty-monolith’s git repo:

our monolith is dusty, and we do have very dusty (and long) directory structure inside the git repository itself. this is where it clicked for me and the Octopus logs started to make sense:

Unhandled error on request: "failed to make directory 'C:/Octopus/Git/FH636WGSP3YMDWB6KSWUP7TLLGAGOQDD/root/worktrees/bAICHQ3PZZY4XMROOMR2BJXAWEI3DTADW': directory exists" LibGit2Sharp.NameConflictException: failed to make directory 'C:/Octopus/Git/FH636WGSP3YMDWB6KSWUP7TLLGAGOQDD/root/worktrees/bAICHQ3PZZY4XMROOMR2BJXAWEI3DTADW': directory exists
   at LibGit2Sharp.Core.Ensure.HandleError(Int32 result) in /opt/buildagent/work/555c65b0f16eb07/LibGit2Sharp/Core/Ensure.cs:line 154
   at LibGit2Sharp.Core.Proxy.git_worktree_add(RepositoryHandle repo, String name, String path, git_worktree_add_options options) in /opt/buildagent/work/555c65b0f16eb07/LibGit2Sharp/Core/Proxy.cs:line 3681
   at LibGit2Sharp.WorktreeCollection.Add(String committishOrBranchSpec, String name, String path, Boolean isLocked) in /opt/buildagent/work/555c65b0f16eb07/LibGit2Sharp/WorktreeCollection.cs:line 72
   at Octopus.Core.Git.Repositories.RepositoryRoot.AddWorktree(GitRef gitRef, String worktreeName, String workingDirectoryPath, CancellationToken cancellationToken) in ./source/Octopus.Core/Git/Repositories/RepositoryRoot.cs:line 158
   at Octopus.Core.Git.Repositories.ErrorHandlingRepositoryRootDecorator.AddWorktree(GitRef gitRef, String worktreeName, String workingDirectoryPath, CancellationToken cancellationToken) in ./source/Octopus.Core/Git/Repositories/ErrorHandlingRepositoryRootDecorator.cs:line 47
   at Octopus.Core.Git.Repositories.FileSystemLoggingRepositoryRootDecorator.AddWorktree(GitRef gitRef, String worktreeName, String workingDirectoryPath, CancellationToken cancellationToken) in ./source/Octopus.Core/Git/Repositories/FileSystemLoggingRepositoryRootDecorator.cs:line 54
   at Octopus.Core.Git.Repositories.SpaceLimitRepositoryRootDecorator.<>c__DisplayClass14_0.<<AddWorktree>b__0>d.MoveNext() in ./source/Octopus.Core/Git/Repositories/SpaceLimitRepositoryRootDecorator.cs:line 44
--- End of stack trace from previous location ---
   at Octopus.Core.Git.GitSpaceLimit.DoOperationWithPostCheck[T](Func`2 operation, CancellationToken cancellationToken, Func`1 onPostFailure) in ./source/Octopus.Core/Git/GitSpaceLimit.cs:line 47
   at Octopus.Core.Git.Repositories.SpaceLimitRepositoryRootDecorator.AddWorktree(GitRef gitRef, String worktreeName, String workingDirectoryPath, CancellationToken cancellationToken) in ./source/Octopus.Core/Git/Repositories/SpaceLimitRepositoryRootDecorator.cs:line 43
   at Octopus.Core.Git.Repositories.GitRepository.CreateRepositoryWorktree(GitRef gitRef, String worktreeName, CancellationToken cancellationToken) in ./source/Octopus.Core/Git/Repositories/GitRepository.cs:line 197
   at Octopus.Core.Git.Repositories.GitRepository.CreateWorktree(GitRef gitRef, String worktreeName, CancellationToken cancellationToken) in ./source/Octopus.Core/Git/Repositories/GitRepository.cs:line 179
   at Octopus.Core.Tasks.AsyncConcurrentDictionary`2.<>c__DisplayClass3_0.<<AddOrUpdate>b__0>d.MoveNext() in ./source/Octopus.Core/Tasks/AsyncConcurrentDictionary.cs:line 43
--- End of stack trace from previous location ---
   at Octopus.Core.Tasks.AsyncConcurrentDictionary`2.InCriticalSection[T](Func`2 action, CancellationToken cancellationToken) in ./source/Octopus.Core/Tasks/AsyncConcurrentDictionary.cs:line 85
   at Octopus.Core.Tasks.AsyncConcurrentDictionary`2.AddOrUpdate(TKey key, Func`2 factoryFunc, Func`3 updateFunc, CancellationToken cancellationToken) in ./source/Octopus.Core/Tasks/AsyncConcurrentDictionary.cs:line 34
   at Octopus.Core.Git.Repositories.GitRepository.PrepareWorkTree(GitRef gitRef, CancellationToken cancellationToken) in ./source/Octopus.Core/Git/Repositories/GitRepository.cs:line 124
   at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException[TResult](Task`1 task)
   at Octopus.Core.Extensions.TaskExtensionMethods.AsSync[T](Task`1 task) in ./source/Octopus.Core/Extensions/TaskExtensionMethods.cs:line 22
   at Octopus.Core.Persistence.Git.GitTransactionFactory.BeginOrAdoptExisting() in ./source/Octopus.Core/Persistence/Git/GitTransactionFactory.cs:line 52
   at Octopus.Core.Persistence.Git.GitPersistenceModule.<>c.<Load>b__7_2(IComponentContext c) in ./source/Octopus.Core/Persistence/Git/GitPersistenceModule.cs:line 100
   at Autofac.Builder.RegistrationBuilder.<>c__DisplayClass0_0`1.<ForDelegate>b__0(IComponentContext c, IEnumerable`1 p)
   at Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget)

I’m especially looking at ./source/Octopus.Core/Git/GitSpaceLimit.cs:line 47

TL;DR:
my assumption is that Octopus’ Version Control feature can’t cope with git repos nearing the maximum of Windows’ Maximum Path Length Limitation

a simple workaround would be creating another git repo containing only the *.ocl files for our monolith but to be honest I kinda like having everything in one repo.
I do wonder though why Octopus Server has to pull everything from the affected repo - only pulling the content ./octopus/dusty-monolith (and therefore not caring about the rest of the repo) would totally be sufficient (for our use case at least).

so… help pls :D?

ninja-edit
remember the "octopus performance bad part? yea, totally forgot about that.
unfortunatly, git repo of monolith = kinda big and lots of files. performance on octopus projects using version control with smaller git repos = faster, but not as fast before (no version control active).

Hi @f.beifuss,

Thank you for contacting Octopus Support. I’m sorry you are running into this issue.

If you haven’t tried it already, I recommend clearing the local Git cache to see if that unblocks you:

If that doesn’t work, you can try removing the directory throwing the error (C:/Octopus/Git/FH636WGSP3YMDWB6KSWUP7TLLGAGOQDD/root/worktrees/bAICHQ3PZZY4XMROOMR2BJXAWEI3DTADW), clear the Git cache once again and see if that unblocks you.

Regarding performance, we are aware that performance is not equivalent with Git enabled projects versus traditional Octopus Projects. We are continually working toward improving this experience. Much of the performance differences come down to Octopus allowing for changes to be made on the Git repo side. Octopus must read the .OCL file to ensure that the current state of the Git repo is consistent with what is displayed in Octopus. Since this information is now external to the database, it can take that extra bit longer to load.

Let me know if clearing the local Git cache works for you at your earliest convenience.

Best Regards,
Donny

Hey Donny,

thanks for the fast reply.
clearing the git cache did the trick, tysm!

still - is there a way I can prevent the whole git repo is being cloned?

Hi @f.beifuss,

Thank you for getting back to me. I’m glad to hear that clearing the Git cache unblocked you.

Regarding the Git repo, the only thing we can suggest at the moment is to make sure the repo is dedicated for Octopus only by either removing non-Octopus-related items or moving the Octopus Git repo to a different location.

If you have any additional questions, please don’t hesitate to reach out.

Best Regards,
Donny