Class: Twit::Repo

Inherits:
Object
  • Object
show all
Defined in:
lib/twit/repo.rb

Overview

An object to represent a git repository.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root = nil) ⇒ Repo

Takes an optional argument of a Dir object to treat as the repository root. If not, try to detect the root of the current repository.

When run without arguments in a directory not part of a git repository, raise NotARepositoryError.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/twit/repo.rb', line 17

def initialize root = nil
  if root.nil?
    stdout, stderr, status = Open3.capture3 "git rev-parse --show-toplevel"
    if status != 0
      case stderr
      when /Not a git repository/
        raise NotARepositoryError
      else
        raise Error, stderr
      end
    end
    root = stdout.strip
  end
  @root = root
end

Instance Attribute Details

#rootObject (readonly)

The root directory of the repository.



10
11
12
# File 'lib/twit/repo.rb', line 10

def root
  @root
end

Instance Method Details

#current_branchObject

Return the current branch.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/twit/repo.rb', line 102

def current_branch
  Dir.chdir @root do
    cmd = "git rev-parse --abbrev-ref HEAD"
    stdout, stderr, status = Open3.capture3 cmd
    if status != 0
      case stderr
      when /unknown revision/
        raise Error, "could not determine branch of repo with no commits"
      when /Not a git repository/
        raise NotARepositoryError
      else
        raise Error, stderr
      end
    end
    return stdout.strip
  end
end

#discardObject

Clean the working directory (permanently deletes changes!!!).



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/twit/repo.rb', line 139

def discard
  Dir.chdir @root do
    # First, add all files to the index. (Otherwise, we won't discard new
    # files.) Then, hard reset to revert to the last saved state.
    cmd = "git add --all && git reset --hard"
    stdout, stderr, status = Open3.capture3 cmd
    if status != 0
      case stderr
      when /Not a git repository/
        raise NotARepositoryError
      else
        raise Error, stderr
      end
    end
  end
end

#include(other_branch) ⇒ Object

Incorperate changes from another branch, but do not commit them.

Return true if the merge was successful without conflicts; false if there are conflicts.



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/twit/repo.rb', line 160

def include other_branch
  Dir.chdir @root do
    cmd = "git merge --no-ff --no-commit \"#{other_branch}\""
    stdout, stderr, status = Open3.capture3 cmd
    if status != 0
      if /Not a git repository/.match stderr
        raise NotARepositoryError
      elsif /Automatic merge failed/.match stdout
        return false
      else
        raise Error, stderr
      end
    end
  end
  return true
end

#include_into(other_branch) ⇒ Object

Reverse of #include – incorperate changes from the current branch into another.



179
180
181
182
183
# File 'lib/twit/repo.rb', line 179

def include_into other_branch
  original_branch = current_branch
  open other_branch
  include(original_branch)
end

#listObject

Return an Array of branches in the repo.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/twit/repo.rb', line 79

def list
  Dir.chdir @root do
    cmd = "git branch"
    stdout, stderr, status = Open3.capture3 cmd
    if status != 0
      case stderr
      when /Not a git repository/
        raise NotARepositoryError
      else
        raise Error, stderr
      end
    end
    return stdout.split.map { |s|
      # Remove trailing/leading whitespace and astericks
      s.sub('*', '').strip
    }.reject { |s|
      # Drop elements created due to trailing newline
      s.size == 0
    }
  end
end

#nothing_to_commit?Boolean

Return true if there is nothing new to commit.

Returns:

  • (Boolean)


186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/twit/repo.rb', line 186

def nothing_to_commit?
  Dir.chdir @root do
    cmd = "git status"
    stdout, stderr, status = Open3.capture3 cmd
    if status != 0
      case stderr
      when /Not a git repository/
        raise NotARepositoryError
      else
        raise Error, stderr
      end
    end
    # Check if status indicates nothing to commit
    return /nothing to commit/.match stdout
  end
end

#open(branch) ⇒ Object

Open a branch.



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/twit/repo.rb', line 121

def open branch
  Dir.chdir @root do
    cmd = "git checkout \"#{branch}\""
    stdout, stderr, status = Open3.capture3 cmd
    if status != 0
      case stderr
      when /Not a git repository/
        raise NotARepositoryError
      when /pathspec '#{branch}' did not match any/
        raise InvalidParameter, "#{branch} does not exist"
      else
        raise Error, stderr
      end
    end
  end
end

#save(message) ⇒ Object

Update the snapshot of the current directory.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/twit/repo.rb', line 34

def save message
  Dir.chdir @root do
    cmd = "git add --all && git commit -m \"#{message}\""
    stdout, stderr, status = Open3.capture3 cmd
    if status != 0
      if /nothing to commit/.match stdout
        raise NothingToCommitError
      elsif /Not a git repository/.match stderr
        raise NotARepositoryError
      else
        raise Error, stderr
      end
    end
  end
end

#saveas(newbranch, message = nil) ⇒ Object

Save the current state of the repository to a new branch.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/twit/repo.rb', line 51

def saveas newbranch, message = nil
  message ||= "Create new branch: #{newbranch}"
  # First, create the new branch and switch to it.
  Dir.chdir @root do
    cmd = "git checkout -b \"#{newbranch}\""
    stdout, stderr, status = Open3.capture3 cmd
    if status != 0
      case stderr
      when /not a valid branch name/
        raise InvalidParameter, "#{newbranch} is not a valid branch name"
      when /already exists/
        raise InvalidParameter, "#{newbranch} already exists"
      when /Not a git repository/
        raise NotARepositoryError
      else
        raise Error, stderr
      end
    end
  end
  # Next, save any working changes.
  begin
    Twit.save message
  rescue NothingToCommitError
    # New changes are not required for saveas.
  end
end