git_auto_checkout 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fc2d259e57441831e2508602620f44fe6389a579
4
+ data.tar.gz: 7110b85ae44612489fc2af228965d4e792771756
5
+ SHA512:
6
+ metadata.gz: 0b6df09b625bbf784fde84e8ef6eedd9505dcd1d92a19840f2309f9a2ebb714e1ce93c48dc0dda573f7746ff224641423e73151901ce69da890b2945472779d1
7
+ data.tar.gz: 251532dd6b62f0ad2b28535149ec21eab3d4e04334e026dbdcd3170bc8e0944dcc85bc43058e3b58cfedf35182881e71f82753d88180efec619f0881a714e164
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ *.sh
data/LICENSE.md ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2014, Sam Rossi
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of git_auto_checkout nor the names of its
15
+ contributors may be used to endorse or promote products derived from
16
+ this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # Installation
2
+
3
+ The repostory is a typical Ruby gem, so it can be installed by cloning and
4
+ locally building the .gem file. As of right now, the gem is *not* published on
5
+ rubygems.org, so `gem install git_auto_checkout` won't work. I expect to publish
6
+ it there sometime soon, but for now, folllow these steps to install:
7
+
8
+ ## Prerequisites
9
+
10
+ You must have git installed on your system, as well as the "gem" command
11
+ available.
12
+
13
+ ## Then run the following commands in your terminal
14
+
15
+ 1. `git clone https://github.com/saghmrossi/git_auto_checkout/`
16
+ 2. `cd git_auto_checkout`
17
+ 3. `gem build git_auto_checkout.gemspec`
18
+ 4. `gem install --local git_auto_checkout*.gem`
19
+
20
+ # Usage
21
+
22
+ Assuming your gem paths are set up properly, the gem installation makes the
23
+ "git_auto_checkout" executable available to you from anywhere. Run it in a
24
+ directory that is a git repository and follow the prompts to checkout branches
25
+ or past commits.
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'git_auto_checkout'
5
+ rescue LoadError
6
+ require 'rubygems'
7
+ require 'git_auto_checkout'
8
+ end
9
+
10
+ GitAutoCheckout.run
@@ -0,0 +1,21 @@
1
+ $:.push File.expand_path('../lib, __FILE__')
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'git_auto_checkout'
5
+ s.version = '0.1.0'
6
+ s.license = 'BSD 3-Clause'
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ['Saghm Rossi']
9
+ s.email = ['saghmrossi@gmail.com']
10
+ s.homepage = ''
11
+ s.summary = %q{Helper to checkout out old commits.}
12
+ s.description = %q{
13
+ Gives a console-based prompt of all of the past commits,
14
+ and allows the user to select one to checkout.
15
+ }
16
+ s.files = `git ls-files`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map do |f|
18
+ File.basename(f)
19
+ end
20
+ s.require_paths = ['lib']
21
+ end
@@ -0,0 +1,220 @@
1
+ require 'git_auto_checkout/git_commit'
2
+
3
+ module GitAutoCheckout
4
+ class GitCheckoutHelper
5
+ # Internal: Gets the Array of GitCommits.
6
+ attr_reader :commits
7
+
8
+ # Internal: Intialize a CheckoutHelper.
9
+ def initialize(page_size = 8)
10
+ @page_size = page_size
11
+ log = `git log`.split("\n")
12
+
13
+ parse_all_commits(log)
14
+ get_git_branches
15
+ end
16
+
17
+ # Internal: Prompt the user to select a past commit or quit, and checkout
18
+ # the past commit if one was selected.
19
+ #
20
+ # Returns nothing.
21
+ def make_commit
22
+ commit_or_branch = prompt_user_until_quit_or_commit_selection
23
+ return unless commit_or_branch
24
+
25
+ git_checkout(commit_or_branch)
26
+ end
27
+
28
+ private
29
+
30
+ # Internal: Go through all the commits and parses out the hash strings and
31
+ # messages.
32
+ #
33
+ # log - String output of `git log`.
34
+ #
35
+ # Returns nothing (adds commits directly to instance variable.
36
+ def parse_all_commits(log)
37
+ @commits = []
38
+ @commits << parse_one_commit(log) until log.empty?
39
+
40
+ # Show commits newest to oldest.
41
+ @commits.reverse
42
+ end
43
+
44
+ # Internal: Prompts user for selection of a past commit.
45
+ #
46
+ # idx - Which commit index to start listing from.
47
+ # error - Incorrect input String previously given, or nil if there was none.
48
+ #
49
+ # Returns hash String of selected commit, or false if none was chosen.
50
+ # Raises error (through #parse_one_commit if the log String is malformed
51
+ # (e.g. each commit message is not preceded and succeeded by an empty line).
52
+ # Raises error (through #parse_commit_hash) if no commit was found.
53
+ def prompt_user_until_quit_or_commit_selection(idx = 0, error=false)
54
+ print_commit_prompt(idx, error)
55
+
56
+ selection = gets.chomp!
57
+ number = selection.to_i
58
+ selection = number if selection == '0' || number != 0
59
+
60
+ return case selection
61
+ when 'b'
62
+ prompt_user_until_quit_or_branch_selection
63
+ when 'q'
64
+ false
65
+ when 'p'
66
+ idx = [idx - @page_size, 0].max
67
+ prompt_user_until_quit_or_commit_selection(idx, false)
68
+ when 'n'
69
+ idx = [idx + @page_size, commits.size - @page_size].min
70
+ idx = [idx, 0].max
71
+ prompt_user_until_quit_or_commit_selection(idx, false)
72
+ when idx...idx + @page_size
73
+ @commits[selection.to_i].hash_string
74
+ else
75
+ selection = invalid_entry(selection)
76
+ prompt_user_until_quit_or_commit_selection(idx, selection)
77
+ end
78
+ end
79
+
80
+ # Internal: Report error if there is one, and prompts user for input.
81
+ #
82
+ # idx - Which commit index to start listing from.
83
+ # error - Incorrect input String previously given, or nil if there was none.
84
+ #
85
+ # Returns nothing.
86
+ def print_commit_prompt(idx, error)
87
+ system 'clear'
88
+
89
+ puts error if error
90
+ puts 'Enter a number to checkout that commit'
91
+ puts 'Enter "b" to see a list of branches to checkout'
92
+ puts 'Enter "p" to scroll to the previous set of commits'
93
+ puts 'Enter "n" to scroll to the next set of commits'
94
+ puts 'Enter "q" to quit without checking out anything'
95
+ puts '----------------------------------------------'
96
+
97
+ @commits[idx...idx + @page_size].each_with_index do |commit, i|
98
+ puts "#{idx + i}: #{commit.message}"
99
+ end
100
+ end
101
+
102
+ # Internal: Remove and parse the first commit from the log and returns it
103
+ # serialized into a GitCommit.
104
+ #
105
+ # log - String output of `git log`.
106
+ #
107
+ # Returns the GitCommit parsed from the log.
108
+ # Raises error if the log String is malformed (e.g. each commit message is
109
+ # not preceded and succeeded by an empty line).
110
+ # Raises error (through #parse_commit_hash) if no commit was found.
111
+ def parse_one_commit(log)
112
+ commit, idx = parse_commit_hash(log)
113
+ log.slice!(0, idx)
114
+
115
+ log.each_with_index do |line, i|
116
+ next unless line.empty?
117
+
118
+ commit.message = log[i + 1].strip
119
+ raise 'weird message ending' if log[i + 2] && !log[i + 2].empty?
120
+
121
+ log.slice!(0, i + 2)
122
+
123
+ return commit
124
+ end
125
+
126
+ raise 'no message found'
127
+ end
128
+
129
+ # Internal: Parse the hash string of the first commt in the log.
130
+ #
131
+ # log - String output of `git log`.
132
+ #
133
+ # Returns the newly created GitCommit and the index of the first line after
134
+ # the hash String found.
135
+ # Raises error if no commit was found.
136
+ def parse_commit_hash(log)
137
+ commit = GitCommit.new
138
+
139
+ log.each_with_index do |line, i|
140
+ line = line.split
141
+ next unless line.first == 'commit'
142
+
143
+ commit.hash_string = line.last
144
+ return commit, i + 1
145
+ end
146
+
147
+ raise 'no commit found'
148
+ end
149
+
150
+ # Internal: Checkouts out a past commit specified by the hash string.
151
+ #
152
+ # commit_hash_string - String of past git commit to checkout.
153
+ #
154
+ # Returns nothing.
155
+ def git_checkout(commit_or_branch)
156
+ system 'clear'
157
+ `git checkout #{commit_or_branch}`
158
+ end
159
+
160
+ def get_git_branches
161
+ @branches = `git branch`.split("\n").reject { |branch| branch.chr == "*" }
162
+ @branches.map!(&:strip)
163
+ end
164
+
165
+ def prompt_user_until_quit_or_branch_selection(idx = 0, error=false)
166
+ if @branches.empty?
167
+ return prompt_user_until_quit_or_commit_selection(
168
+ 0,
169
+ 'No other branches exist'
170
+ )
171
+ end
172
+
173
+ print_branch_prompt(idx, error)
174
+
175
+ selection = gets.chomp!
176
+ number = selection.to_i
177
+ selection = number if selection == '0' || number != 0
178
+
179
+ return case selection
180
+ when 'c'
181
+ prompt_user_until_quit_or_commit_selection
182
+ when 'q'
183
+ false
184
+ when 'p'
185
+ idx = [idx - @page_size, 0].max
186
+ prompt_user_until_quit_or_branch_selection(idx, false)
187
+ when 'n'
188
+ idx = [idx + @page_size, commits.size - @page_size].min
189
+ prompt_user_until_quit_or_branch_selection(idx, false)
190
+ when idx...idx + @page_size
191
+ @branches[selection.to_i]
192
+ else
193
+ selection = invalid_entry(selection)
194
+ prompt_user_until_quit_or_branch_selection(idx, selection)
195
+ end
196
+ end
197
+
198
+
199
+ def print_branch_prompt(idx, error)
200
+ system 'clear'
201
+
202
+ puts error if error
203
+ puts 'Enter a number to checkout that branch'
204
+ puts 'Enter "c" to see a list of commits to checkout'
205
+ puts 'Enter "p" to scroll to the previous set of commits'
206
+ puts 'Enter "n" to scroll to the next set of commits'
207
+ puts 'Enter "q" to quit without checking out anything'
208
+ puts '----------------------------------------------'
209
+
210
+ @branches[idx...idx + @page_size].each_with_index do |branch, i|
211
+ puts "#{idx + i}: #{branch}"
212
+ end
213
+ end
214
+
215
+ def invalid_entry(error)
216
+ "Invalid entry \"#{error}\"; try again"
217
+ end
218
+ end # End class
219
+ end # End module
220
+ 1
@@ -0,0 +1,9 @@
1
+ module GitAutoCheckout
2
+ class GitCommit
3
+ # Internal: Gets/Sets the hash String of this GitCommit.
4
+ attr_accessor :hash_string
5
+
6
+ # Internal: Gets/Sets the message String of this GitCommit.
7
+ attr_accessor :message
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'git_auto_checkout/git_checkout_helper'
4
+
5
+ module GitAutoCheckout
6
+ module_function
7
+
8
+ def run
9
+ if `git rev-parse --is-inside-work-tree 2>&1`.split.first == "fatal:"
10
+ $stderr.puts "Error: current directory is not a git repository"
11
+ exit 1
12
+ end
13
+
14
+ git_checkout_helper = GitCheckoutHelper.new
15
+ git_checkout_helper.make_commit
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git_auto_checkout
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Saghm Rossi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: "\n Gives a console-based prompt of all of the past
14
+ commits,\n and allows the user to select one to checkout.\n
15
+ \ "
16
+ email:
17
+ - saghmrossi@gmail.com
18
+ executables:
19
+ - git_auto_checkout
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - ".gitignore"
24
+ - LICENSE.md
25
+ - README.md
26
+ - bin/git_auto_checkout
27
+ - git_auto_checkout.gemspec
28
+ - lib/git_auto_checkout.rb
29
+ - lib/git_auto_checkout/git_checkout_helper.rb
30
+ - lib/git_auto_checkout/git_commit.rb
31
+ homepage: ''
32
+ licenses:
33
+ - BSD 3-Clause
34
+ metadata: {}
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project:
51
+ rubygems_version: 2.4.1
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Helper to checkout out old commits.
55
+ test_files: []