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
# File 'lib/twit/repo.rb', line 17

def initialize root = nil
  if root.nil?
    begin
      root = Rugged::Repository.discover(Dir.getwd)
    rescue Rugged::RepositoryError
      raise NotARepositoryError
    end
  end
  @git = Rugged::Repository.new(root)
  @root = @git.workdir
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.



93
94
95
96
97
98
99
# File 'lib/twit/repo.rb', line 93

def current_branch
  ref = Rugged::Reference.lookup(@git, 'HEAD').resolve
  if not ref.branch?
    raise Error, "Not currently on a branch."
  end
  ref.name.split('/').last
end

#discardObject

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



110
111
112
113
114
115
116
# File 'lib/twit/repo.rb', line 110

def discard
  # First, add all files to the index. (Otherwise, we won't discard new
  # files.) Then, hard reset to revert to the last saved state.
  @git.index.add_all
  @git.index.write
  @git.reset('HEAD', :hard)
end

#listObject

Return an Array of branches in the repo.



88
89
90
# File 'lib/twit/repo.rb', line 88

def list
  Rugged::Branch.each_name(@git, :local).to_a
end

#nothing_to_commit?Boolean

Return true if there is nothing new to commit.

Returns:

  • (Boolean)


129
130
131
132
133
134
# File 'lib/twit/repo.rb', line 129

def nothing_to_commit?
  @git.status do |file, status|
    return false unless status.empty?
  end
  return true
end

#open(branch) ⇒ Object

Open a branch.

Raises:



102
103
104
105
106
107
# File 'lib/twit/repo.rb', line 102

def open branch
  ref = Rugged::Branch.lookup(@git, branch)
  raise InvalidParameter, "#{branch} is not a branch" if ref.nil?
  @git.head = ref.canonical_name
  @git.reset('HEAD', :hard)
end

#rewind(amount) ⇒ Object

Create a new branch at the specified commit id (may permanently lose commits!!!).

Raises:



120
121
122
123
124
125
126
# File 'lib/twit/repo.rb', line 120

def rewind amount
  raise UnsavedChanges unless nothing_to_commit?
  raise ArgumentError, "Expected integer amount" unless amount.is_a? Integer
  @git.index.add_all
  @git.index.write
  @git.reset("HEAD~#{amount}", :hard)
end

#save(message) ⇒ Object

Update the snapshot of the current directory.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/twit/repo.rb', line 30

def save message
  raise NothingToCommitError if nothing_to_commit?
  @git.index.add_all
  @git.index.write
  usr = {name: @git.config['user.name'],
         email: @git.config['user.email'],
         time: Time.now}
  opt = {}
  opt[:tree] = @git.index.write_tree
  opt[:author] = usr
  opt[:committer] = usr
  opt[:message] = message
  opt[:parents] = unless @git.empty?
                    begin
                      [@git.head.target].compact
                    rescue Rugged::ReferenceError
                      []
                    end
                  else [] end
  opt[:update_ref] = 'HEAD'
  Rugged::Commit.create(@git, opt)
end

#saveas(newbranch, message = nil) ⇒ Object

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



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/twit/repo.rb', line 54

def saveas newbranch, message = nil
  message ||= "Create new branch: #{newbranch}"
  begin
    if @git.empty?
      # For an empty repo, we can "create a new branch" by setting HEAD to
      # a symbolic reference to the new branch. Then, the next commit will
      # create that branch (instead of master).
      Rugged::Reference.create(@git, 'HEAD',
           "refs/heads/#{newbranch}", true)
    else
      # For a non-empty repo, we just create a new branch and switch to it.
      branch = @git.create_branch newbranch
      @git.head = branch.canonical_name
    end
  rescue Rugged::ReferenceError => error
    case error.message
    when /is not valid/
      raise InvalidParameter, "#{newbranch} is not a valid branch name"
    when /already exists/
      raise InvalidParameter, "#{newbranch} already exists"
    else
      raise Error, "Internal Rugged error: #{error.message}"
    end
  end

  # Next, save any working changes.
  begin
    save message
  rescue NothingToCommitError
    # New changes are not required for saveas.
  end
end