git_auto_checkout 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []