git-process-lib 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/CHANGELOG.md +123 -0
  2. data/Gemfile +21 -0
  3. data/Gemfile.lock +57 -0
  4. data/LICENSE +193 -0
  5. data/README.md +342 -0
  6. data/Rakefile +32 -0
  7. data/bin/git-new-fb +39 -0
  8. data/bin/git-pull-request +63 -0
  9. data/bin/git-sync +38 -0
  10. data/bin/git-to-master +44 -0
  11. data/docs/git-new-fb.1.adoc +83 -0
  12. data/docs/git-process.1.adoc +227 -0
  13. data/docs/git-pull-request.1.adoc +166 -0
  14. data/docs/git-sync.1.adoc +120 -0
  15. data/docs/git-to-master.1.adoc +172 -0
  16. data/git-new-fb.gemspec +20 -0
  17. data/git-process-lib.gemspec +25 -0
  18. data/git-process.gemspec +22 -0
  19. data/git-pull-request.gemspec +20 -0
  20. data/git-sync.gemspec +20 -0
  21. data/git-to-master.gemspec +20 -0
  22. data/lib/git-process/abstract_error_builder.rb +53 -0
  23. data/lib/git-process/changed_file_helper.rb +115 -0
  24. data/lib/git-process/git_abstract_merge_error_builder.rb +130 -0
  25. data/lib/git-process/git_branch.rb +105 -0
  26. data/lib/git-process/git_branches.rb +81 -0
  27. data/lib/git-process/git_config.rb +135 -0
  28. data/lib/git-process/git_lib.rb +646 -0
  29. data/lib/git-process/git_logger.rb +84 -0
  30. data/lib/git-process/git_merge_error.rb +28 -0
  31. data/lib/git-process/git_process.rb +159 -0
  32. data/lib/git-process/git_process_error.rb +18 -0
  33. data/lib/git-process/git_process_options.rb +101 -0
  34. data/lib/git-process/git_rebase_error.rb +30 -0
  35. data/lib/git-process/git_remote.rb +222 -0
  36. data/lib/git-process/git_status.rb +108 -0
  37. data/lib/git-process/github_configuration.rb +298 -0
  38. data/lib/git-process/github_pull_request.rb +165 -0
  39. data/lib/git-process/new_fb.rb +49 -0
  40. data/lib/git-process/parked_changes_error.rb +41 -0
  41. data/lib/git-process/pull_request.rb +136 -0
  42. data/lib/git-process/pull_request_error.rb +25 -0
  43. data/lib/git-process/rebase_to_master.rb +148 -0
  44. data/lib/git-process/sync_process.rb +55 -0
  45. data/lib/git-process/syncer.rb +157 -0
  46. data/lib/git-process/uncommitted_changes_error.rb +23 -0
  47. data/lib/git-process/version.rb +22 -0
  48. data/local-build.rb +24 -0
  49. data/spec/FileHelpers.rb +19 -0
  50. data/spec/GitRepoHelper.rb +123 -0
  51. data/spec/changed_file_helper_spec.rb +127 -0
  52. data/spec/git_abstract_merge_error_builder_spec.rb +64 -0
  53. data/spec/git_branch_spec.rb +123 -0
  54. data/spec/git_config_spec.rb +45 -0
  55. data/spec/git_lib_spec.rb +176 -0
  56. data/spec/git_logger_spec.rb +66 -0
  57. data/spec/git_process_spec.rb +208 -0
  58. data/spec/git_remote_spec.rb +227 -0
  59. data/spec/git_status_spec.rb +122 -0
  60. data/spec/github_configuration_spec.rb +152 -0
  61. data/spec/github_pull_request_spec.rb +117 -0
  62. data/spec/github_test_helper.rb +49 -0
  63. data/spec/new_fb_spec.rb +126 -0
  64. data/spec/pull_request_helper.rb +94 -0
  65. data/spec/pull_request_spec.rb +137 -0
  66. data/spec/rebase_to_master_spec.rb +362 -0
  67. data/spec/spec_helper.rb +21 -0
  68. data/spec/sync_spec.rb +1474 -0
  69. metadata +249 -0
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env rake
2
+ #require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+ require 'yard'
5
+ require 'yard/rake/yardoc_task'
6
+ require 'fileutils'
7
+ require File.expand_path('../lib/git-process/version', __FILE__)
8
+
9
+ desc 'Default: run specs.'
10
+ task :default => :spec
11
+
12
+ desc "Run specs"
13
+ RSpec::Core::RakeTask.new do |t|
14
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
15
+ end
16
+
17
+ desc "Create docs"
18
+ YARD::Rake::YardocTask.new
19
+
20
+ desc 'Update manpage from asciidoc file'
21
+ task :manpage do
22
+ FileUtils::rm_r('man') if File.directory?('man')
23
+ FileUtils::mkdir('man')
24
+ %x[find docs/ -type f -exec a2x -a version=#{GitProc::Version::STRING} -f manpage -D man {} \\;]
25
+ end
26
+
27
+ desc 'Update htmldoc from asciidoc file'
28
+ task :htmldoc do
29
+ FileUtils::rm_r('htmldoc') if File.directory?('htmldoc')
30
+ FileUtils::mkdir('htmldoc')
31
+ system('find docs/ -type f -exec a2x -f xhtml -D htmldoc {} \;')
32
+ end
data/bin/git-new-fb ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #require "rubygems"
4
+ #require "bundler/setup"
5
+ #$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '../lib')
6
+
7
+ require 'git-process/git_process_options'
8
+ require 'git-process/new_fb'
9
+ require 'git-process/git_lib'
10
+ include GitProc
11
+
12
+
13
+ class NewFeatureBranchOptions
14
+ include GitProcessOptions
15
+
16
+
17
+ def usage(filename)
18
+ "#{filename} [options] branch_name"
19
+ end
20
+
21
+
22
+ def empty_argv_ok?
23
+ false
24
+ end
25
+
26
+
27
+ def extend_opts(parser)
28
+ parser.opt :local, "Do not do a fetch first if there is a remote defined", :short => :l, :default => false
29
+ end
30
+
31
+
32
+ def post_parse(opts, argv)
33
+ opts[:branch_name] = argv.shift
34
+ end
35
+
36
+ end
37
+
38
+ opts = NewFeatureBranchOptions.new.parse_cli(File.basename(__FILE__), ARGV)
39
+ GitProc::NewFeatureBranch.new(GitProc::GitLib.new('.', opts), opts).run
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #require "rubygems"
4
+ #require "bundler/setup"
5
+ #$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '../lib')
6
+
7
+ require 'git-process/git_lib'
8
+ require 'git-process/pull_request'
9
+ require 'git-process/git_process_options'
10
+ include GitProc
11
+
12
+ class PullRequestOptions
13
+ include GitProcessOptions
14
+
15
+
16
+ def description
17
+ <<DESC
18
+ DESCRIPTION
19
+
20
+
21
+ DESC
22
+ end
23
+
24
+
25
+ def usage(filename)
26
+ "Usage: #{filename} [ options ] [pull_request_title | server/pull_request_number | pull_request_number]"
27
+ end
28
+
29
+
30
+ def extend_opts(parser)
31
+ parser.opt :base_branch, "The branch on the server that you want this \"pulled\" into. "+
32
+ "Defaults to the integration branch.", :type => :string
33
+ parser.opt :head_branch, "The branch that you want reviewed before being \"pulled\" "+
34
+ "into the base branch. Defaults to the current branch.", :type => :string
35
+ parser.opt :repo_name, "The name of the repository to \"pull\" into. Defaults to "+
36
+ "the current repository.", :type => :string
37
+ parser.opt :description, "The description of the Pull Request. Usually includes a "+
38
+ "nice description of what was changed to make things easier "+
39
+ "for the reviewer.", :short => :d, :type => :string
40
+ parser.opt :user, "Your GitHub username. Only needed the first time you connect, "+
41
+ "and you will be prompted for it if needed.", :type => :string
42
+ parser.opt :password, "Your GitHub password. Only needed the first time you connect, "+
43
+ "and you will be prompted for it if needed.", :type => :string
44
+ end
45
+
46
+
47
+ def post_parse(opts, argv)
48
+ arg = argv.shift
49
+ if /^\d+$/ =~ arg
50
+ opts[:prNumber] = arg
51
+ elsif /^(.*)\/(\d+)$/ =~ arg
52
+ m = /^(.*)\/(\d+)$/.match(arg)
53
+ opts[:server] = m[1]
54
+ opts[:prNumber] = m[2]
55
+ else
56
+ opts[:title] = arg
57
+ end
58
+ end
59
+
60
+ end
61
+
62
+ opts = PullRequestOptions.new.parse_cli(File.basename(__FILE__), ARGV)
63
+ GitProc::PullRequest.new(GitProc::GitLib.new('.', opts), opts).run
data/bin/git-sync ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #require "rubygems"
4
+ #require "bundler/setup"
5
+ #$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '../lib')
6
+
7
+ require 'git-process/git_process_options'
8
+ require 'git-process/sync_process'
9
+ require 'git-process/git_lib'
10
+
11
+
12
+ class SyncOptions
13
+ include GitProc::GitProcessOptions
14
+
15
+
16
+ def extend_opts(parser)
17
+ parser.opt :rebase, "Rebase instead of merge against the integration branch", :default => true
18
+ parser.opt :merge, "Merge instead of rebase against the integration branch", :short => :none, :default => false
19
+ parser.opt :force, "Force the push; defaults to true if --rebase is used", :short => :f, :default => false
20
+ parser.opt :local, "Do not do a push; gets remote changes, but does not update the server", :short => :l, :default => false
21
+
22
+ parser.conflicts :rebase, :merge
23
+ parser.conflicts :local, :force
24
+ end
25
+
26
+
27
+ #noinspection RubyUnusedLocalVariable
28
+ def post_parse(opts, argv)
29
+ opts[:force] = true if opts[:rebase]
30
+ opts[:merge] = !opts[:rebase]
31
+
32
+ opts[:branch_name] = argv.shift
33
+ end
34
+
35
+ end
36
+
37
+ opts = SyncOptions.new.parse_cli(File.basename(__FILE__), ARGV)
38
+ GitProc::Sync.new(GitProc::GitLib.new('.', opts), opts).run
data/bin/git-to-master ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #require "rubygems"
4
+ #require "bundler/setup"
5
+ #$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '../lib')
6
+
7
+ require 'git-process/git_process_options'
8
+ require 'git-process/rebase_to_master'
9
+ require 'git-process/git_lib'
10
+
11
+
12
+ class ToMasterOptions
13
+ include GitProc::GitProcessOptions
14
+
15
+
16
+ def usage(filename)
17
+ "Usage: #{filename} [ options ] [server/pull_request_number | pull_request_number]"
18
+ end
19
+
20
+
21
+ def extend_opts(parser)
22
+ parser.opt :keep, "Don't do any \"cleanup.\" It keeps the current local "+
23
+ "and remote branches, and does not close any "+
24
+ "outstanding pull requests.", :short => :k, :default => false
25
+ end
26
+
27
+
28
+ def post_parse(opts, argv)
29
+ arg = argv.shift
30
+ if /^\d+$/ =~ arg
31
+ opts[:prNumber] = arg
32
+ elsif /^(.*)\/(\d+)$/ =~ arg
33
+ m = /^(.*)\/(\d+)$/.match(arg)
34
+ opts[:server] = m[1]
35
+ opts[:prNumber] = m[2]
36
+ else
37
+ # "normal" to-master
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ opts = ToMasterOptions.new.parse_cli(File.basename(__FILE__), ARGV)
44
+ GitProc::RebaseToMaster.new(GitProc::GitLib.new('.', opts), opts).run
@@ -0,0 +1,83 @@
1
+ GIT-NEW-FB(1)
2
+ =============
3
+ :doctype: manpage
4
+
5
+
6
+ NAME
7
+ ----
8
+ git-new-fb - Create a new feature branch based on the integration branch.
9
+
10
+
11
+ SYNOPSIS
12
+ --------
13
+ 'git-new-fb' ['OPTIONS'] [ 'branchname' ]
14
+
15
+
16
+ OPTIONS
17
+ -------
18
+
19
+ The effective default is "*git new-fb -i* 'branch_name'".
20
+
21
+ *-l, --local*::
22
+ Do not do a fetch first if there is a remote defined
23
+
24
+ *--info*::
25
+ Informational messages; show the major things this is doing (*default: true*)
26
+
27
+ *-q, --quiet*::
28
+ Quiet messages; only show errors
29
+
30
+ *-v, --verbose*::
31
+ Verbose messages; show lots of details on what this is doing
32
+
33
+ *--version*::
34
+ Print version and exit
35
+
36
+
37
+ CONFIGURATION
38
+ -------------
39
+
40
+ Options for 'git-new-fb(1)' are set using 'git-config(1)'.
41
+
42
+ *gitProcess.remoteName*::
43
+ Allows you to explicitly set the remote server name to use. Defaults
44
+ to the first server name reported by 'git-remote(1)'.
45
+
46
+ *gitProcess.integrationBranch*::
47
+ Allows you to explicitly set the integration branch to use. Defaults
48
+ to "master".
49
+
50
+
51
+ EXAMPLE
52
+ -------
53
+
54
+ Assuming that the the integration branch on the server is "master",
55
+ running "git new-fb my_feature" will do roughly the following
56
+ for you:
57
+
58
+ $ git fetch -p
59
+ $ git checkout my_feature origin/master
60
+
61
+ Also, if you are currently on the "_parking_" branch (see 'git-to-master(1)'),
62
+ this will remove that branch.
63
+
64
+
65
+ SEE ALSO
66
+ --------
67
+
68
+ *git-process*(1), *git-to-master*(1), *git-sync*(1), *git-pull-request*(1)
69
+
70
+
71
+ BUGS
72
+ ----
73
+ Known bug list: <https://github.com/jdigger/git-process/issues?state=open>
74
+
75
+
76
+ AUTHOR
77
+ ------
78
+ git-new-fb has been written primarily by Jim Moore.
79
+
80
+
81
+ RESOURCES
82
+ ---------
83
+ Main web site: <https://github.com/jdigger/git-process>
@@ -0,0 +1,227 @@
1
+ = GIT-PROCESS(1) =
2
+ :doctype: manpage
3
+
4
+
5
+ == NAME ==
6
+ git-process - A suite of tools to make it easy to use an easy and robust git process.
7
+
8
+
9
+ == DESCRIPTION ==
10
+ 'git-process(1)' consists of a small suite of tools that make it easy to follow a simple, consistent process
11
+ that scales from simple one-person projects to very large (dozens of developers) collaboration. It does this
12
+ by taking advantage of "classic" methodologies like "Git Flow" and GitHub pull requests to have "just enough"
13
+ process. See <<WE00,*WORKFLOW EXAMPLES*>> to see this in practice.
14
+
15
+
16
+ == COMMON OPTIONS ==
17
+
18
+ *--info*::
19
+ Informational messages; show the major things this is doing (*default: true*)
20
+
21
+ *-q, --quiet*::
22
+ Quiet messages; only show errors
23
+
24
+ *-v, --verbose*::
25
+ Verbose messages; show lots of details on what this is doing
26
+
27
+ *--version*::
28
+ Print version and exit
29
+
30
+
31
+ == CONFIGURATION ==
32
+
33
+ *gitProcess.remoteName*::
34
+ Allows you to explicitly set the remote server name to use. Defaults
35
+ to the first server name reported by 'git-remote(1)'.
36
+
37
+ *gitProcess.integrationBranch*::
38
+ Allows you to explicitly set the integration branch to use. Defaults
39
+ to "master".
40
+
41
+ *gitProcess.defaultRebaseSync*::
42
+ Should 'git-sync(1)' use *--rebase* by default instead of *--merge*? Defaults to *true*.
43
+
44
+ *gitProcess.github.authtoken*::
45
+ Not meant to be set manually, this is the OAuth token used to communicate
46
+ with the GitHub server. If it is not set, the user will be prompted for their credentials.
47
+
48
+ *github.user*::
49
+ If OAuth needs to prompt for credentials, if this value is set then it is
50
+ used as the username. Otherwise it is unused.
51
+
52
+
53
+ [[WE00]]
54
+ == WORKFLOW EXAMPLES ==
55
+
56
+ === WORKING ALONE ON A LOCAL-ONLY PROJECT ===
57
+
58
+ Jim is working on "my_project" and needs to start work on a new feature.
59
+
60
+ [a_branch]$ git new-fb save_the_planet
61
+ Creating save_tp off of master
62
+ [save_the_planet]$
63
+
64
+ He does lots of work. Checkin, checkin, checkin.
65
+
66
+ A sudden new brilliant idea happens.
67
+
68
+ [save_the_planet]$ git new-fb shave_the_bunnies
69
+ Creating shave_the_bunnies off of master
70
+ [shave_the_bunnies]$
71
+
72
+ After creating a Sheering class and tests, he commits his changes.
73
+
74
+ [shave_the_bunnies]$ git commit
75
+ [shave_the_bunnies]$ git to-master
76
+ Rebasing shave_the_bunnies against master
77
+ Removing branch 'shave_the_bunnies'
78
+ [_parking_]$
79
+
80
+ Time to get back to work on "save_the_planet".
81
+
82
+ [_parking_]$ git checkout save_the_planet
83
+ [save_the_planet]$ git sync
84
+ Rebasing save_the_planet against master
85
+ [save_the_planet]$
86
+
87
+ Do more work. Commit. Commit. Commit.
88
+
89
+ [save_the_planet]$ git sync
90
+ Rebasing save_the_planet against master
91
+ [save_the_planet]$
92
+
93
+ Liking to have a clean history, he squashes and edits the commits to hide
94
+ the evidence of false starts and stupid ideas so that anyone who sees the
95
+ code in the future will think he was simply a genius.
96
+
97
+ [save_the_planet]$ git rebase -i
98
+ Rebasing save_the_planet against master
99
+ [save_the_planet]$ git to-master
100
+ Rebasing save_the_planet against master
101
+ Removing branch 'save_the_planet'
102
+ [_parking_]$
103
+
104
+ Time to release to a grateful world.
105
+
106
+
107
+ === WORKING WITH A TEAM ===
108
+
109
+ John, Alice, Bill and Sally are working on "big_monies." Alice and John are pairing and
110
+ need to start work on a new feature.
111
+
112
+ john-[a_branch]$ git new-fb steal_underpants
113
+ Fetching the latest changes from the server
114
+ Creating steal_underpants off of origin/master
115
+ john-[steal_underpants]$
116
+
117
+ They do lots of work. Checkin, checkin, checkin. It has a lot of steps...
118
+
119
+ Meanwhile Bill has been working on his great idea:
120
+
121
+ bill-[some_branch]$ git new-fb awesomo4000
122
+ Fetching the latest changes from the server
123
+ Creating awesomo4000 off of origin/master
124
+ bill-[awesomo4000]$
125
+
126
+ He creates his "Laaaaame" class and checks it in, with a pull request asking Sally to do a code review.
127
+
128
+ bill-[awesomo4000]$ git commit
129
+ bill-[awesomo4000]$ git pull-request "A.W.E.S.O.M-0 4000 prototype" \
130
+ -d "@sally, can you make sure Butters won't recognize it?"
131
+ Pushing to 'awesomo4000' on 'origin'.
132
+ Creating a pull request asking for 'awesomo4000' to be merged into 'master' on big_monies.
133
+ Created pull request at https://github.com/big_monies/pull/3454
134
+ bill-[awesomo4000]$
135
+
136
+ Sally sees the email. After looking at it in the web interface, she wants to test it.
137
+
138
+ sally-[other_branch]$ git pull-request 3454
139
+ Getting #pr_number
140
+ Fetching the latest changes from the server
141
+ new branch: awesomo4000
142
+ Setting upstream/tracking for branch 'awesomo4000' to 'origin/master'.
143
+ sally-[awesomo4000]$ git sync
144
+ Fetching the latest changes from the server
145
+ Rebasing awesomo4000 against origin/master
146
+ Pushing to 'awesomo4000' on 'origin'.
147
+ sally-[awesomo4000]$
148
+
149
+ After verifying that the tests still work and "it's all good" she promotes the code to integration.
150
+
151
+ sally-[awesomo4000]$ git to-master
152
+ Fetching the latest changes from the server
153
+ Rebasing awesomo4000 against origin/master
154
+ Pushing to 'awesomo4000' on 'origin'.
155
+ Removing branch remote 'awesomo4000'
156
+ Removing branch local 'awesomo4000'
157
+ Closing a pull request #3454 on origin.
158
+ sally-[_parking_]$
159
+
160
+ Over lunch Alice gets a brainstorm ("a duck and rubber hose!") and rushes off to her computer:
161
+
162
+ alice-[lens_cap]$ git sync steal_underpants
163
+ Fetching the latest changes from the server
164
+ Creating steal_underpants off of origin/steal_underpants
165
+ Setting upstream/tracking for branch 'steal_underpants' to 'origin/master'.
166
+ alice-[steal_underpants]$
167
+
168
+ She makes her changes, syncs back up with the server, and heads over to pair with John again.
169
+
170
+ alice-[steal_underpants]$ git commit
171
+ alice-[steal_underpants]$ git sync
172
+ Fetching the latest changes from the server
173
+ Rebasing steal_underpants against origin/master
174
+ Pushing to 'steal_underpants' on 'origin'.
175
+ alice-[steal_underpants]$
176
+
177
+ John, meanwhile, had made some changes of his own.
178
+
179
+ john-[steal_underpants]$ git commit
180
+ john-[steal_underpants]$ git sync
181
+ Fetching the latest changes from the server
182
+ Remote branch has changed
183
+ Rebasing steal_underpants against origin/steal_underpants
184
+ Rebasing steal_underpants against origin/master
185
+ Pushing to 'steal_underpants' on 'origin'.
186
+ john-[steal_underpants]$
187
+
188
+ At this point, his local branch has Alice's change as well as Bill and
189
+ Sally's A.W.E.S.O.M-O 4000 enhancements.
190
+
191
+ After confirming with Alice and Bill that everything looks good, he
192
+ pushes his changes up for integration.
193
+
194
+ john-[steal_underpants]$ git to-master
195
+ Fetching the latest changes from the server
196
+ Rebasing steal_underpants against origin/master
197
+ Pushing to 'steal_underpants' on 'origin'.
198
+ Removing remote branch 'steal_underpants'
199
+ Removing local branch 'steal_underpants'
200
+ [_parking_]$
201
+
202
+ Profit!!
203
+
204
+
205
+ == CONTROL FILES ==
206
+
207
+ *gitprocess-sync-\***--**::
208
+ To help make the process simpler and more reliable, 'git-sync(1)' will put a file in the "'.git'" directory
209
+ that contains the SHA-1 of the last successful sync to the server. 'git-to-master(1)' will remove the file
210
+ as part of its normal "housekeeping."
211
+
212
+
213
+ == SEE ALSO ==
214
+
215
+ *git-sync*(1), *git-to-master*(1), *git-new-fb*(1), *git-pull-request*(1)
216
+
217
+
218
+ == BUGS ==
219
+ Known bug list: <https://github.com/jdigger/git-process/issues?state=open>
220
+
221
+
222
+ == AUTHOR ==
223
+ git-process has been written primarily by Jim Moore.
224
+
225
+
226
+ == RESOURCES ==
227
+ Main web site: <https://github.com/jdigger/git-process>