Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Git.open causes ArgumentError (When assigning attributes, you must pass a hash as an argument, String passed.) #707

Closed
RaviPatel opened this issue Apr 17, 2024 · 7 comments

Comments

@RaviPatel
Copy link

RaviPatel commented Apr 17, 2024

Subject of the issue

Running Git.open in a rails environment throws ArgumentError (When assigning attributes, you must pass a hash as an argument, String passed.)

Your environment

  • git version 2.34.1
  • ruby-git version 1.19.1
  • ruby 2.7.1p83
  • rails 6.1.4

Steps to reproduce

  1. I have a git directory in /home/app/git/hello-world
  2. Run rails c
  3. Run require 'git'
  4. Run Git.open('/home/app/git/hello-world')
  5. Error: ArgumentError (When assigning attributes, you must pass a hash as an argument, String passed.)

Expected/Actual behaviour

When I run the same commands in IRB (i.e., not rails environment), I correctly receive the Git::Base instance. I should receive this same object in the rails environment, but I get the error instead.

@jcouball
Copy link
Member

jcouball commented Apr 26, 2024

Can you please provide the complete error? I am not sure where the error is coming from.

Do you have a model in your rails project (or some other class) named Git (in the top level namespace)? Before you run Git.open, what is the output of puts Git.method(:open).source_location?

I am having trouble duplicating your environment. If you could provide a dockerfile that builds an image that can be used to demonstrate the error, that would be ideal. Or if your project is OpenSource, point me to the Github repository.

@RaviPatel
Copy link
Author

RaviPatel commented Apr 26, 2024

Thanks @jcouball for your reply.

irb(main):007:0> puts Git.method(:open).source_location
/usr/local/rvm/gems/ruby-2.7.8/gems/git-1.19.1/lib/git.rb
380
=> nil

Yes, I do have a namespace Git in the project. The project is private, so I cannot share the code but I can share some snippets...
Gemfile:

gem 'git', '~> 1.19.1', require: false

lib/clients.rb:

module Clients
  def self.git
    require 'git'
    @@git_client ||= Git
  end
end

app/jobs/git/repository_traversing_job.rb:

class Git::RepositoryTraversingJob < ApplicationJob
  queue_as :git_processing

  def perform(repository_id, commit_hash_id)
    repository = Git::Repository.find(repository_id)

    git = nil
    if File.exist?(repository.working_dir)
      git = Clients.git.open(repository.working_dir, repository: repository.ssh_url, log: Logger.new(STDOUT))
    else
      git = Clients.git.clone(repository.ssh_url, repository.name, path: "/home/app/git/")
    end

  end
end

Both the clone and open commands return the same error:

...2024-04-26 04:16:38.972294 D [80:7160 mysql.rb:14] (99.7ms) ActiveRecord -- Git::Repository Load -- {:sql=>"SELECT `git_repositories`.*
=> #<Git::Repository id: 500000, name: "hello-world", html_url: "https://github.com/fake/hello-world...", ss...
irb(main):006:0> git = Clients.git.open(repository.working_dir, repository: repository.ssh_url, log: Logger.new(STDOUT))
I, [2024-04-26T04:17:09.238012 #80]  INFO -- : Starting Git
Traceback (most recent call last):
        1: from (irb):6
ArgumentError (When assigning attributes, you must pass a hash as an argument, String passed.)
irb(main):010:0> File.exist?(repository.working_dir)
=> false
irb(main):011:0> git = Clients.git.clone(repository.ssh_url, repository.name, path: "/home/app/git/")
Traceback (most recent call last):
        1: from (irb):11
ArgumentError (When assigning attributes, you must pass a hash as an argument, String passed.)
irb(main):011:0> git = Clients.git.clone(repository.ssh_url, repository.name, path: "/home/app/git/")
Traceback (most recent call last):
        1: from (irb):11
ArgumentError (When assigning attributes, you must pass a hash as an argument, String passed.)

@jcouball
Copy link
Member

Just to be sure, what does the following output?

puts Clients.git.class
puts Clients.git.method(:open).source_location

@RaviPatel
Copy link
Author

irb(main):005:0> pp Clients.git.method(:open).source_location
["/usr/local/rvm/gems/ruby-2.7.8/gems/git-1.19.1/lib/git.rb", 380]
=> ["/usr/local/rvm/gems/ruby-2.7.8/gems/git-1.19.1/lib/git.rb", 380]
irb(main):006:0> pp Clients.git.class
Module
=> Module

@jcouball
Copy link
Member

If you rename your Git module does that make any difference?

@RaviPatel
Copy link
Author

RaviPatel commented Apr 29, 2024

Yes, if I delete the Git module in my repo, the clone/open functions seem to be working. Is there a way I can keep the Git module in my repo and still use this gem?

@jcouball
Copy link
Member

Unfortunately, something that you or Rails is doing conflicts with the Git gem.

Remember, when you open Git:: and add stuff there like your own classes, you are modifying the same module that is part of the git gem. This is the double edge sword of Ruby being able to re-open the definition of modules and classes to add new things or even change existing things.

Generally, you should create a module structure that does not open other modules and make changes to them. I would recommend a structure under lib/ that starts with a module that is unique to your project. Otherwise, you are creating land mines for yourself that may come back to haunt you later. Something like MyRailsProject::Git.

I don't think this is a problem with the git gem so I am closing this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants