{"action":"created","comment":{"url":"https://api.github.com/repos/ryanai3/rgit/pulls/comments/38605880","id":38605880,"diff_hunk":"@@ -64,4 +51,112 @@ def test(*args)\n       puts args\n     end\n   end\n-end\n\\ No newline at end of file\n+end\n+\n+module Impl\n+  class Cli\n+    def format_options(option_hash)\n+      result = \"\"\n+      option_hash.each { |k, v|\n+        key_str = \" --#{k.to_s.gsub(\"_\", \"-\")}\"\n+        case v # v is truthy in all cases except: nil, false\n+        when [true, false].include?(v) # it's a boolean\n+          result << key_str\n+        when String\n+          result << key_str << \"=#{v}\"\n+        when Fixnum\n+          result << key_str << \"=#{v}\"\n+        when Hash\n+          v.each { |key, val|\n+            result << key_str << \" #{key}=#{val}\"\n+          }\n+        end\n+      }\n+      result\n+    end\n+\n+    def lowest_repo_above(start_dir)\n+      res_dir = nil\n+      start_dir.ascend { |dir|\n+        if dir.has_child? \".git\"\n+          res_dir = dir\n+          break\n+        end\n+      }\n+      res_dir\n+    end\n+\n+    def git_command(cmd, opt_str, dir)\n+      capture_pty_stdout(\"git #{cmd} #{opt_str}\", dir)\n+    end\n+\n+    # Opens a virtual shell at the specified\n+    # dir and runs the given cmd\n+    def capture_pty_stdout(cmd, dir)\n+      result = ''\n+      PTY.spawn(\"cd #{dir.realpath}; #{cmd}\") do |stdout, stdin, pid|\n+        begin\n+          stdout.each { |line| result += line }\n+        rescue Errno::EIO #Done getting output\n+          result\n+        end\n+      end\n+      result\n+    end\n+\n+\n+    def init_subrepo(parent_dir, subrepo_dir)\n+\n+    end\n+\n+    def init_repo(directory, options)\n+      # Check if a git repository exists.\n+      already_has_git = directory.has_child?(\".git\")\n+      # 1. Initialize a git repository w/ provided options\n+      git_command(\"init\", format_options(options), directory)\n+\n+      puts(\"Initialized empty rGit repository in #{directory}\") unless options[:quiet]\n+    end\n+\n+    def initial_repo_setup(directory)\n+      # 1. Add a fake original commit so that we can graft once and for all\n+      #    and a fake first commit to have the original as its parent\n+      git_command(\"commit\", \"--allow-empty -m \\\"original in #{directory}\\\"\", directory)\n+      git_command(\"commit\", \"--allow-empty -m \\\"first commit in #{directory}\\\"\", directory)\n+      # 2. Add a graft so we have a fake \"first commit\" for all subrepos\n+      # that we can use for cthulhu merges :)\n+      first_commit, orig_commit = git_command(\"log\", \"--format=%H -n2\", directory).split(\"\\n\")\n+      Grafts.append_to_grafts!(directory, first_commit, orig_commit)\n+    end\n+  end\n+\n+  class Grafts < Hash\n+    def self.from_git(directory)\n+      @location = directory + \".git/info/grafts\"\n+      res = new\n+      @location.open.readlines.each do |line|\n+        # Shas are 40 characters, first sha is child\n+        # TODO: HANDLE GRAFT FILES W/ MORE THAN ONE FAKE PARENT FOR A COMMIT\n+        res.store(*line.gsub(\" \", \"\").slice(40))\n+      end\n+      res\n+    end\n+\n+    def self.append_to_grafts!(directory, child_sha, parent_sha)\n+      File.open(directory + \".git/info/grafts\", \"a\") {\n+          |f| f << \"#{child_sha} #{parent_sha}\\n\"\n+      }\n+    end\n+\n+    def write_to_disk!","path":"lib/rgit/cli.rb","position":145,"original_position":145,"commit_id":"8b96e10fe7a3d0520a717be8a0b70f6b5a1e58f9","original_commit_id":"8b96e10fe7a3d0520a717be8a0b70f6b5a1e58f9","user":{"login":"houndci","id":6697940,"avatar_url":"https://avatars.githubusercontent.com/u/6697940?v=3","gravatar_id":"","url":"https://api.github.com/users/houndci","html_url":"https://github.com/houndci","followers_url":"https://api.github.com/users/houndci/followers","following_url":"https://api.github.com/users/houndci/following{/other_user}","gists_url":"https://api.github.com/users/houndci/gists{/gist_id}","starred_url":"https://api.github.com/users/houndci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/houndci/subscriptions","organizations_url":"https://api.github.com/users/houndci/orgs","repos_url":"https://api.github.com/users/houndci/repos","events_url":"https://api.github.com/users/houndci/events{/privacy}","received_events_url":"https://api.github.com/users/houndci/received_events","type":"User","site_admin":false},"body":"Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.","created_at":"2015-09-03T01:40:23Z","updated_at":"2015-09-03T01:40:23Z","html_url":"https://github.com/ryanai3/rgit/pull/1#discussion_r38605880","pull_request_url":"https://api.github.com/repos/ryanai3/rgit/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/ryanai3/rgit/pulls/comments/38605880"},"html":{"href":"https://github.com/ryanai3/rgit/pull/1#discussion_r38605880"},"pull_request":{"href":"https://api.github.com/repos/ryanai3/rgit/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/ryanai3/rgit/pulls/1","id":44052367,"html_url":"https://github.com/ryanai3/rgit/pull/1","diff_url":"https://github.com/ryanai3/rgit/pull/1.diff","patch_url":"https://github.com/ryanai3/rgit/pull/1.patch","issue_url":"https://api.github.com/repos/ryanai3/rgit/issues/1","number":1,"state":"open","locked":false,"title":"rgit-init","user":{"login":"ryanai3","id":8884501,"avatar_url":"https://avatars.githubusercontent.com/u/8884501?v=3","gravatar_id":"","url":"https://api.github.com/users/ryanai3","html_url":"https://github.com/ryanai3","followers_url":"https://api.github.com/users/ryanai3/followers","following_url":"https://api.github.com/users/ryanai3/following{/other_user}","gists_url":"https://api.github.com/users/ryanai3/gists{/gist_id}","starred_url":"https://api.github.com/users/ryanai3/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ryanai3/subscriptions","organizations_url":"https://api.github.com/users/ryanai3/orgs","repos_url":"https://api.github.com/users/ryanai3/repos","events_url":"https://api.github.com/users/ryanai3/events{/privacy}","received_events_url":"https://api.github.com/users/ryanai3/received_events","type":"User","site_admin":false},"body":"ability to init new repos & subrepos","created_at":"2015-09-02T22:51:46Z","updated_at":"2015-09-03T01:40:23Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7f1b85b530f6ac96f6aaac7f3c246cf634891af1","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/ryanai3/rgit/pulls/1/commits","review_comments_url":"https://api.github.com/repos/ryanai3/rgit/pulls/1/comments","review_comment_url":"https://api.github.com/repos/ryanai3/rgit/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ryanai3/rgit/issues/1/comments","statuses_url":"https://api.github.com/repos/ryanai3/rgit/statuses/8b96e10fe7a3d0520a717be8a0b70f6b5a1e58f9","head":{"label":"ryanai3:rgit-init","ref":"rgit-init","sha":"8b96e10fe7a3d0520a717be8a0b70f6b5a1e58f9","user":{"login":"ryanai3","id":8884501,"avatar_url":"https://avatars.githubusercontent.com/u/8884501?v=3","gravatar_id":"","url":"https://api.github.com/users/ryanai3","html_url":"https://github.com/ryanai3","followers_url":"https://api.github.com/users/ryanai3/followers","following_url":"https://api.github.com/users/ryanai3/following{/other_user}","gists_url":"https://api.github.com/users/ryanai3/gists{/gist_id}","starred_url":"https://api.github.com/users/ryanai3/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ryanai3/subscriptions","organizations_url":"https://api.github.com/users/ryanai3/orgs","repos_url":"https://api.github.com/users/ryanai3/repos","events_url":"https://api.github.com/users/ryanai3/events{/privacy}","received_events_url":"https://api.github.com/users/ryanai3/received_events","type":"User","site_admin":false},"repo":{"id":41829066,"name":"rgit","full_name":"ryanai3/rgit","owner":{"login":"ryanai3","id":8884501,"avatar_url":"https://avatars.githubusercontent.com/u/8884501?v=3","gravatar_id":"","url":"https://api.github.com/users/ryanai3","html_url":"https://github.com/ryanai3","followers_url":"https://api.github.com/users/ryanai3/followers","following_url":"https://api.github.com/users/ryanai3/following{/other_user}","gists_url":"https://api.github.com/users/ryanai3/gists{/gist_id}","starred_url":"https://api.github.com/users/ryanai3/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ryanai3/subscriptions","organizations_url":"https://api.github.com/users/ryanai3/orgs","repos_url":"https://api.github.com/users/ryanai3/repos","events_url":"https://api.github.com/users/ryanai3/events{/privacy}","received_events_url":"https://api.github.com/users/ryanai3/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ryanai3/rgit","description":"Recursive git!","fork":false,"url":"https://api.github.com/repos/ryanai3/rgit","forks_url":"https://api.github.com/repos/ryanai3/rgit/forks","keys_url":"https://api.github.com/repos/ryanai3/rgit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ryanai3/rgit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ryanai3/rgit/teams","hooks_url":"https://api.github.com/repos/ryanai3/rgit/hooks","issue_events_url":"https://api.github.com/repos/ryanai3/rgit/issues/events{/number}","events_url":"https://api.github.com/repos/ryanai3/rgit/events","assignees_url":"https://api.github.com/repos/ryanai3/rgit/assignees{/user}","branches_url":"https://api.github.com/repos/ryanai3/rgit/branches{/branch}","tags_url":"https://api.github.com/repos/ryanai3/rgit/tags","blobs_url":"https://api.github.com/repos/ryanai3/rgit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ryanai3/rgit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ryanai3/rgit/git/refs{/sha}","trees_url":"https://api.github.com/repos/ryanai3/rgit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ryanai3/rgit/statuses/{sha}","languages_url":"https://api.github.com/repos/ryanai3/rgit/languages","stargazers_url":"https://api.github.com/repos/ryanai3/rgit/stargazers","contributors_url":"https://api.github.com/repos/ryanai3/rgit/contributors","subscribers_url":"https://api.github.com/repos/ryanai3/rgit/subscribers","subscription_url":"https://api.github.com/repos/ryanai3/rgit/subscription","commits_url":"https://api.github.com/repos/ryanai3/rgit/commits{/sha}","git_commits_url":"https://api.github.com/repos/ryanai3/rgit/git/commits{/sha}","comments_url":"https://api.github.com/repos/ryanai3/rgit/comments{/number}","issue_comment_url":"https://api.github.com/repos/ryanai3/rgit/issues/comments{/number}","contents_url":"https://api.github.com/repos/ryanai3/rgit/contents/{+path}","compare_url":"https://api.github.com/repos/ryanai3/rgit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ryanai3/rgit/merges","archive_url":"https://api.github.com/repos/ryanai3/rgit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ryanai3/rgit/downloads","issues_url":"https://api.github.com/repos/ryanai3/rgit/issues{/number}","pulls_url":"https://api.github.com/repos/ryanai3/rgit/pulls{/number}","milestones_url":"https://api.github.com/repos/ryanai3/rgit/milestones{/number}","notifications_url":"https://api.github.com/repos/ryanai3/rgit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ryanai3/rgit/labels{/name}","releases_url":"https://api.github.com/repos/ryanai3/rgit/releases{/id}","created_at":"2015-09-02T21:38:19Z","updated_at":"2015-09-02T21:38:59Z","pushed_at":"2015-09-03T01:40:22Z","git_url":"git://github.com/ryanai3/rgit.git","ssh_url":"git@github.com:ryanai3/rgit.git","clone_url":"https://github.com/ryanai3/rgit.git","svn_url":"https://github.com/ryanai3/rgit","homepage":null,"size":0,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"ryanai3:master","ref":"master","sha":"7c60135dcdd80330e079602dfbe2fb7a8b87e607","user":{"login":"ryanai3","id":8884501,"avatar_url":"https://avatars.githubusercontent.com/u/8884501?v=3","gravatar_id":"","url":"https://api.github.com/users/ryanai3","html_url":"https://github.com/ryanai3","followers_url":"https://api.github.com/users/ryanai3/followers","following_url":"https://api.github.com/users/ryanai3/following{/other_user}","gists_url":"https://api.github.com/users/ryanai3/gists{/gist_id}","starred_url":"https://api.github.com/users/ryanai3/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ryanai3/subscriptions","organizations_url":"https://api.github.com/users/ryanai3/orgs","repos_url":"https://api.github.com/users/ryanai3/repos","events_url":"https://api.github.com/users/ryanai3/events{/privacy}","received_events_url":"https://api.github.com/users/ryanai3/received_events","type":"User","site_admin":false},"repo":{"id":41829066,"name":"rgit","full_name":"ryanai3/rgit","owner":{"login":"ryanai3","id":8884501,"avatar_url":"https://avatars.githubusercontent.com/u/8884501?v=3","gravatar_id":"","url":"https://api.github.com/users/ryanai3","html_url":"https://github.com/ryanai3","followers_url":"https://api.github.com/users/ryanai3/followers","following_url":"https://api.github.com/users/ryanai3/following{/other_user}","gists_url":"https://api.github.com/users/ryanai3/gists{/gist_id}","starred_url":"https://api.github.com/users/ryanai3/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ryanai3/subscriptions","organizations_url":"https://api.github.com/users/ryanai3/orgs","repos_url":"https://api.github.com/users/ryanai3/repos","events_url":"https://api.github.com/users/ryanai3/events{/privacy}","received_events_url":"https://api.github.com/users/ryanai3/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ryanai3/rgit","description":"Recursive git!","fork":false,"url":"https://api.github.com/repos/ryanai3/rgit","forks_url":"https://api.github.com/repos/ryanai3/rgit/forks","keys_url":"https://api.github.com/repos/ryanai3/rgit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ryanai3/rgit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ryanai3/rgit/teams","hooks_url":"https://api.github.com/repos/ryanai3/rgit/hooks","issue_events_url":"https://api.github.com/repos/ryanai3/rgit/issues/events{/number}","events_url":"https://api.github.com/repos/ryanai3/rgit/events","assignees_url":"https://api.github.com/repos/ryanai3/rgit/assignees{/user}","branches_url":"https://api.github.com/repos/ryanai3/rgit/branches{/branch}","tags_url":"https://api.github.com/repos/ryanai3/rgit/tags","blobs_url":"https://api.github.com/repos/ryanai3/rgit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ryanai3/rgit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ryanai3/rgit/git/refs{/sha}","trees_url":"https://api.github.com/repos/ryanai3/rgit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ryanai3/rgit/statuses/{sha}","languages_url":"https://api.github.com/repos/ryanai3/rgit/languages","stargazers_url":"https://api.github.com/repos/ryanai3/rgit/stargazers","contributors_url":"https://api.github.com/repos/ryanai3/rgit/contributors","subscribers_url":"https://api.github.com/repos/ryanai3/rgit/subscribers","subscription_url":"https://api.github.com/repos/ryanai3/rgit/subscription","commits_url":"https://api.github.com/repos/ryanai3/rgit/commits{/sha}","git_commits_url":"https://api.github.com/repos/ryanai3/rgit/git/commits{/sha}","comments_url":"https://api.github.com/repos/ryanai3/rgit/comments{/number}","issue_comment_url":"https://api.github.com/repos/ryanai3/rgit/issues/comments{/number}","contents_url":"https://api.github.com/repos/ryanai3/rgit/contents/{+path}","compare_url":"https://api.github.com/repos/ryanai3/rgit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ryanai3/rgit/merges","archive_url":"https://api.github.com/repos/ryanai3/rgit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ryanai3/rgit/downloads","issues_url":"https://api.github.com/repos/ryanai3/rgit/issues{/number}","pulls_url":"https://api.github.com/repos/ryanai3/rgit/pulls{/number}","milestones_url":"https://api.github.com/repos/ryanai3/rgit/milestones{/number}","notifications_url":"https://api.github.com/repos/ryanai3/rgit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ryanai3/rgit/labels{/name}","releases_url":"https://api.github.com/repos/ryanai3/rgit/releases{/id}","created_at":"2015-09-02T21:38:19Z","updated_at":"2015-09-02T21:38:59Z","pushed_at":"2015-09-03T01:40:22Z","git_url":"git://github.com/ryanai3/rgit.git","ssh_url":"git@github.com:ryanai3/rgit.git","clone_url":"https://github.com/ryanai3/rgit.git","svn_url":"https://github.com/ryanai3/rgit","homepage":null,"size":0,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ryanai3/rgit/pulls/1"},"html":{"href":"https://github.com/ryanai3/rgit/pull/1"},"issue":{"href":"https://api.github.com/repos/ryanai3/rgit/issues/1"},"comments":{"href":"https://api.github.com/repos/ryanai3/rgit/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/ryanai3/rgit/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/ryanai3/rgit/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ryanai3/rgit/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/ryanai3/rgit/statuses/8b96e10fe7a3d0520a717be8a0b70f6b5a1e58f9"}}}}