{"action":"created","comment":{"url":"https://api.github.com/repos/ryanai3/rgit/pulls/comments/39201845","id":39201845,"diff_hunk":"@@ -1,31 +1,234 @@\n-\n+require 'byebug'\n+# stdlib imports\n+require \"pathname\"\n+# gem imports\n require \"thor\"\n+require \"rugged\"\n+require \"parseconfig\"\n+# Local imports\n+require_relative \"descriptions\"\n+require_relative \"version\"\n+# Monkey Patches - import\n+require \"core_extensions/pathname/easychildcheck.rb\"\n+# Monkey Patches - apply\n+Pathname.include CoreExtensions::Pathname::EasyChildCheck\n \n-module Rgit\n-  class Cli < Thor\n+module Impl\n+\n+end\n+\n+module Wrappers\n+  class Branches\n+    include Impl\n+    attr_accessor :current_group, :current_branch\n+    def initialize(dir)\n+      @groups = get_branches(dir)\n+      @dir = dir\n+      update\n+      @groups2branch = flat_hash(@groups).each.select { |k, v|\n+\n+      }\n+\n+    end\n+\n+    def update\n+      @groups = self.get_branches(@dir)\n+      @current_branch = git_command(\"symbolic-ref\", \"HEAD\", @dir)\n+                            .strip.gsub(\"refs/heads/\", \"\")\n+      @current_group = @current_branch[1..-1].split(\"/\", 2)[0]\n+    end\n+\n+    def flat_hash(h,f=[],g={})\n+      return g.update({ f=>h }) unless h.is_a? Hash\n+      h.each { |k,r| flat_hash(r,f+[k],g) }\n+      g\n+    end\n+\n+    def get_branches(dir)\n+      self.class.get_branches(dir)\n+    end\n+\n+    def self.get_branches(dir)\n+      heads = dir + \".git/refs/heads\"\n+      groups = heads.children.select do |path|\n+        path.basename.to_s.start_with?(\"@\")\n+      end\n+      # remove first char(\"@\") from group, extract branches\n+      groups.map{|group| [group.basename.to_s[1..-1], extract_branches(group)]}.to_h\n+    end\n+\n+    def extract_branches(path)\n+      self.class.extract_branches(path)\n+    end\n \n-    no_commands {\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+    def self.extract_branches(path)\n+      res = {}\n+      if path.directory?\n+        path.children.each do |child|\n+          name = child.basename.to_s\n+          if name.start_with?(\"%\")\n+            res[:sitting_branch] = child.to_s.split(\".git/refs/heads/\", 2)[1]\n+          else\n+            res[name] = extract_branches(child)\n           end\n+        end\n+      end\n+      res\n+    end\n+\n+    def groups\n+      @groups.keys\n+    end\n+\n+    def [](group)\n+      structure = @groups[group]\n+      flat_hash(structure).values\n+    end\n+\n+    def branch_for_path(path)\n+      branch = nil\n+      so_far = @groups[@current_group]\n+      path.realpath.relative_path_from(@dir).descend do |f|\n+        file_str = f.basename.to_s\n+        sitting_branch = so_far[:sitting_branch]\n+        branch = sitting_branch if sitting_branch\n+        so_far = so_far[file_str]\n+      end\n+      branch\n+    end\n+\n+    def path_for_branch(branch_fullname)\n+      # branchname is a fully qualified path from top git repo\n+      # + other info\n+      # i.e. #{group}/full/path/to/#{sub_branch}\n+      # unless it's a group-level branch in which case\n+      # #{group}/%group\n+      group, branch = branch_fullname.split(\"/\", 2)\n+      path = branch.rpartition(\"%\")[0]\n+      @dir + path\n+    end\n+  end\n+\n+  class Grafts\n+    attr_accessor :location\n+    def initialize(location)\n+      @location = location\n+      @grafts = {}\n+    end\n+\n+    def [](key)\n+      @grafts[key]\n+    end\n+\n+    def []=(key, value)\n+      @grafts[key] = value\n+    end\n+\n+    def self.from_git(directory)\n+      location = directory + \".git/info/grafts\"\n+      res = new(location)\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+        key, value = line.gsub(\" \", \"\").scan(/.{40}/)\n+        res[key] = value\n+      end\n+      res\n+    end\n+\n+    def self.append_to_grafts!(directory, child_sha, parent_sha)\n+      graft_dir = directory + \".git/info\"\n+      FileUtils.mkdir_p(graft_dir)\n+\n+      if (graft_dir + \"grafts\").exist?\n+        grafts = from_git(directory)\n+        grafts[child_sha] = parent_sha\n+        grafts.write_to_disk!\n+      else\n+        File.open(graft_dir + \"grafts\", \"w\") { |file|\n+          file.puts \"#{child_sha} #{parent_sha}\"\n         }\n-        result\n       end\n-    }\n+    end\n+\n+    def self.graft_to_base!(directory, child_sha)\n+      parent_sha = File.open(\n+          directory + \".git/refs/heads/@rgit-base-for-graft\",\n+          &:readline).strip\n+      append_to_grafts!(directory, child_sha, parent_sha)\n+    end\n+\n+    def write_to_disk!\n+      FileUtils.mkdir_p(@location.dirname)\n+      File.open(@location, 'w') do |f|\n+        @grafts.each do |k, v|\n+          f << \"#{k} #{v}\\n\"\n+        end\n+      end\n+    end\n+  end\n+\n+  #contains the info for a subrepo from the perspective of the parent","path":"lib/rgit/cli.rb","position":192,"original_position":192,"commit_id":"287a3cf8d0d36bd6b8505d381b622514599147e9","original_commit_id":"287a3cf8d0d36bd6b8505d381b622514599147e9","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":"Missing space after #.","created_at":"2015-09-10T19:22:03Z","updated_at":"2015-09-10T19:22:03Z","html_url":"https://github.com/ryanai3/rgit/pull/1#discussion_r39201845","pull_request_url":"https://api.github.com/repos/ryanai3/rgit/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/ryanai3/rgit/pulls/comments/39201845"},"html":{"href":"https://github.com/ryanai3/rgit/pull/1#discussion_r39201845"},"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-10T19:22:03Z","closed_at":null,"merged_at":null,"merge_commit_sha":"535fdb962333b22955d689554959a9e810abe56e","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/287a3cf8d0d36bd6b8505d381b622514599147e9","head":{"label":"ryanai3:rgit-init","ref":"rgit-init","sha":"287a3cf8d0d36bd6b8505d381b622514599147e9","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-10T19:21:53Z","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":180,"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-10T19:21:53Z","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":180,"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/287a3cf8d0d36bd6b8505d381b622514599147e9"}}}}