Here at RANDOMTYPE we use gollum as an internal wiki for keeping track of important things like server setup steps, solutions to problems we’ve solved, unix tips and tricks we’ve found, and the like. So when I got this friendly error from gollum I was a bit concerned:
The full stack trace was big and ugly:
Grit::GitRuby::Internal::LooseObjectError - size mismatch: /.rbenv/lib/ruby/gems/1.9.1/gems/grit-2.4.1/lib/grit/git-ruby/internal/loose.rb:59:in `get_raw_object' /.rbenv/lib/ruby/gems/1.9.1/gems/grit-2.4.1/lib/grit/git-ruby/internal/loose.rb:32:in `[]' /.rbenv/lib/ruby/gems/1.9.1/gems/grit-2.4.1/lib/grit/git-ruby/repository.rb:84:in `block in get_raw_object_by_sha1' /.rbenv/lib/ruby/gems/1.9.1/gems/grit-2.4.1/lib/grit/git-ruby/repository.rb:83:in `each' /.rbenv/lib/ruby/gems/1.9.1/gems/grit-2.4.1/lib/grit/git-ruby/repository.rb:83:in `get_raw_object_by_sha1' /.rbenv/lib/ruby/gems/1.9.1/gems/grit-2.4.1/lib/grit/git-ruby/repository.rb:105:in `get_object_by_sha1' /.rbenv/lib/ruby/gems/1.9.1/gems/grit-2.4.1/lib/grit/git-ruby/repository.rb:155:in `cat_file' /.rbenv/lib/ruby/gems/1.9.1/gems/grit-2.4.1/lib/grit/git-ruby.rb:27:in `block in cat_file' /.rbenv/lib/ruby/gems/1.9.1/gems/grit-2.4.1/lib/grit/git-ruby.rb:224:in `block in try_run' /.rbenv/lib/ruby/1.9.1/timeout.rb:58:in `timeout' /.rbenv/lib/ruby/gems/1.9.1/gems/grit-2.4.1/lib/grit/git-ruby.rb:223:in `try_run' /.rbenv/lib/ruby/gems/1.9.1/gems/grit-2.4.1/lib/grit/git-ruby.rb:27:in `cat_file' /.rbenv/lib/ruby/gems/1.9.1/gems/grit-2.4.1/lib/grit/blob.rb:43:in `data' /.rbenv/lib/ruby/gems/1.9.1/gems/gollum-1.3.1/lib/gollum/page.rb:151:in `raw_data' /.rbenv/lib/ruby/gems/1.9.1/gems/gollum-1.3.1/lib/gollum/page.rb:160:in `text_data' /.rbenv/lib/ruby/gems/1.9.1/gems/gollum-1.3.1/lib/gollum/markup.rb:15:in `initialize' /.rbenv/lib/ruby/gems/1.9.1/gems/gollum-1.3.1/lib/gollum/page.rb:171:in `new' /.rbenv/lib/ruby/gems/1.9.1/gems/gollum-1.3.1/lib/gollum/page.rb:171:in `formatted_data' /.rbenv/lib/ruby/gems/1.9.1/gems/gollum-1.3.1/lib/gollum/frontend/app.rb:190:in `show_page_or_file' /.rbenv/lib/ruby/gems/1.9.1/gems/gollum-1.3.1/lib/gollum/frontend/app.rb:182:in `block in <class:App>' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1152:in `call' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1152:in `block in compile!' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:724:in `instance_eval' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:724:in `route_eval' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:708:in `block (2 levels) in route!' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:758:in `block in process_route' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:755:in `catch' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:755:in `process_route' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:707:in `block in route!' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:706:in `each' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:706:in `route!' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:843:in `dispatch!' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:644:in `block in call!' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:808:in `instance_eval' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:808:in `block in invoke' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:808:in `catch' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:808:in `invoke' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:644:in `call!' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:629:in `call' /.rbenv/lib/ruby/gems/1.9.1/gems/rack-1.3.3/lib/rack/head.rb:9:in `call' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/showexceptions.rb:21:in `call' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1272:in `block in call' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1303:in `synchronize' /.rbenv/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1272:in `call' /.rbenv/lib/ruby/gems/1.9.1/gems/rack-1.3.3/lib/rack/handler/webrick.rb:59:in `service' /.rbenv/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service' /.rbenv/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run' /.rbenv/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'
Because we have a ton of important information in that repository, if it became corrupt that would be a bad thing! Not being able to rely on an internal system of documentation is a big deal, so I needed to get to the bottom of the issue.
Step 1 – The Googles!
Obviously finding a solution to the problem is much easier, and faster than trying to track it down myself. The first search result on the string Grit::GitRuby::Internal::LooseObjectError - size mismatch turned up the following page: https://github.com/mojombo/grit/issues/65 and the first comment on the issue looked similar to my issue:
This is already fixed in master, installing the current master branch fixes the issue:
https://github.com/mojombo/grit/commit/593f6cae465aa6d4b089cede8dc0cd8c4b5fe6cc
I also opened a ticket for gollum: https://github.com/github/gollum/issues/147
Following that link to the gollum repository I got a bug report about Umlaut (UTF-8) characters causing the issue. That certainly wasn’t my issue since the string that was breaking my repository was this:
* [[Meta-programming in Ruby: It’s All About the Self|http://yehudakatz.com/2009/11/15/metaprogramming-in-ruby-its-all-about-the-self/]]
So what I had was a potential solution for the problem I was experiencing.
Step 2 – Applying the Fix
Now this was a really small fix, and I would prefer not to update Grit until the gollum team pulled the changes into the gollum repository and I also don’t know for sure if this patch was going to solve my issue. So instead I opened up the gem and added the patch myself. You can rake me over the coals later for this unsafe practice if you like.
This last year I took Marc-André Cournoyer’s awesome Owning Rails Course where he taught me about the useful gemedit gem. With gemedit you can open up gem code quickly and easily into your favorite text editor. It’s really a brilliant piece of work for quickly diving into gem code, and allows you to explore, poke, and prod at the code on your box.
So if you don’t have it gem install gemedit will get it installed on your machine. Then you could run the command:
gem edit grit
Whichever editor you have setup in your GEMEDITOR, BUNDLER_EDITOR, VISUAL or EDITOR environment variable will load with a tree of the grit source. I use vim and have nerdtree installed so this works nicely – not sure if it works without nerdtree.
I navigated to lib/grit/git-ruby/internal/loose.rb, and made the 5 changes from length to bytesize which was in the patch referenced earlier. Super easy. Save the document, and the gem has been modified.
At this point I restarted the gollum server so that it could pick up the gem changes. I then pasted in my offending reference to Yehuda Katz, and saved the wiki post. No Error!
And there you have it, a quick and easy application of gemedit, and how it can be used to patch a gem.
Pingback: Last Week’s Top Ruby News: Rails 3.1.3, autoload deprecated, and conferences