rugged icon indicating copy to clipboard operation
rugged copied to clipboard

Rugged::OSError - Could not open file for writing: No such file or directory

Open daveverwer opened this issue 6 years ago • 2 comments

I'm having a problem with Rugged running in production on Linux. Of course, it may not be specific to my production environment, but that's the only place I can reproduce it! I can not reproduce it on my local development machine.

I'm getting an error when calling checkout with a tag name, although it also happens when checking out from an oid so I don't think it's anything specifically related to it being a tag name.

	4: from rugged_checkout_bug.rb:4:in `<main>'
	3: from rugged_checkout_bug.rb:4:in `each'
	2: from rugged_checkout_bug.rb:6:in `block in <main>'
	1: from /home/xxxxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rugged-0.28.3.1/lib/rugged/repository.rb:52:in `checkout'
	
/home/xxxxxx/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rugged-0.28.3.1/lib/rugged/repository.rb:52:in `checkout_tree': could not open '/home/xxxxxx/rugged_bug/repo/RxSwift/Platform/Platform.Darwin.swift' for writing: No such file or directory (Rugged::OSError)

I originally thought that the bug was tied to specific commits in specific repositories, but it seems to be more related to just checking out multiple revisions in a loop. It does happen consistently, and some repositories (even if they have a very large number of tags) are fine, whereas some are not.

The good news is that I have managed to reproduce it with a simple sample script and a single repository. It may appear to be a timing issue, but in the real world application this is reproduction code is derived from significant processing is happening in between each checkout, and in the reproduction code below also raises an error if there is a sleep() in each iteration.

Before running this code, check out https://github.com/ReactiveX/RxSwift.git into a directory called repo below where this sample script lives.

require 'rugged'
  
repository = Rugged::Repository.new('./repo/')
repository.tags.each do |tag|
        puts "tag: #{tag.name}"
        repository.checkout(tag.name, strategy: :force)
end

For me, on my server, this raises an error consistently when checking out tag 3.0.0-beta.1 after checking out 38 previous tags. It's not specific to that tag though as reversing the array it raises an error when checking out tag 3.2.0 after only processing 25 other tags.

The original code that I extracted the code above from iterates over 1,000 repositories, checking out over 18,000 tags from those repositories. That code never crashes on my local development machine, and only crashes on the server for 35 tags in 4 repositories out of the 18,000+ tags in 1,000+ repositories.

Development Environment (never raises an error):

  • macOS 10.14.6
  • ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]

Production Environment (raises an error consistently):

  • Linux 4.15.0-60-generic #67-Ubuntu SMP Thu Aug 22 16:55:30 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
  • ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]

If there's any other information I can provide then please let me know.

daveverwer avatar Sep 03 '19 16:09 daveverwer

Out of curiosity, when you say check out that repository, is there anything interesting going on? Do you reproduce this from a straight-up git clone of that repo or is there perhaps some other tooling that does the clone / checkout / etc?

ethomson avatar Sep 03 '19 17:09 ethomson

So on the server in the production code it's originally cloned with Rugged::Repository.clone_at and then checked out. The server does also pull updates to those repositories regularly, but this error exists even after just an initial clone using clone_at.

With the sample script above, it was a clone made with the git command line tool.

daveverwer avatar Sep 04 '19 13:09 daveverwer