Skip to content
This repository
Browse code

feature-pluck: Clean up after pluck

After cherry-picking the commits over to the new feature, reset --hard
the commits out of the original branch so there's no longer a duplicate
copy of that commit.
  • Loading branch information...
commit 87ee5589bc4257dc8d9d00983b2537f785c55db1 1 parent 70cdc0e
Tim Asp authored March 22, 2013
40  bin/feature
@@ -188,20 +188,44 @@ when 'pluck'
188 188
 
189 189
    feature = ARGV[1]
190 190
    sha = ARGV[2]
  191
+   original_branch = Git::current_branch
191 192
 
192  
-   exit if !confirm("Create feature branch named: '#{feature}' and pluck '#{sha}' out of the current branch and onto it?")
  193
+   if Git::branch_exists(feature)
  194
+      exit if !confirm("Pluck '#{sha}' out of the current branch and onto #{feature}?")
193 195
 
194  
-   Git::run_safe("git pull --rebase")
195  
-   Git::run_safe("git checkout -b #{feature} origin/#{Git::development_branch}")
196  
-
197  
-   Git::init_submodules
  196
+      Git::run_safe("feature switch #{feature}")
  197
+   else
  198
+      exit if !confirm("Pluck '#{sha}' out of the current branch and onto a new feature #{feature}?")
198 199
 
199  
-   # Automatically setup remote tracking branch
200  
-   Git::branch_config(feature)
  200
+      Git::run_safe("feature start #{feature}")
  201
+   end
201 202
 
202  
-   # cherry pick the commits from your local master onto the new feature
  203
+   # cherry-pick the commits from your local master onto the new feature
203 204
    Git::run_safe("git cherry-pick #{sha}")
204 205
 
  206
+   # Jump back to the original branch
  207
+   Git::run_safe("git checkout \"#{original_branch}\"")
  208
+
  209
+   # We're dealing with a range of commits
  210
+   if (sha.include? "...")
  211
+      sha_list = `git rev-list #{sha}^`.split("\n")
  212
+      for commit in sha_list
  213
+         Git::run_safe("git show #{commit}")
  214
+      end
  215
+
  216
+      sha = sha_list.last
  217
+   else
  218
+      Git::run_safe("git show #{sha}")
  219
+   end
  220
+
  221
+   exit if !confirm("Are you sure you want to remove these commits from #{original_branch}?")
  222
+
  223
+   # Blow away the original commits we plucked over to the new branch, we
  224
+   # don't need them anymore
  225
+   Git::run_safe("git reset --hard #{sha}^")
  226
+
  227
+   # Finally switch back to your new, plucked, feature
  228
+   Git::run_safe("git checkout \"#{feature}\"")
205 229
 else
206 230
    display_feature_help
207 231
 end
22  lib/git.rb
@@ -78,6 +78,12 @@ def self.branch_info(branch)
78 78
       sprintf "%-30s %s", simple_branch, branch_info
79 79
    end
80 80
 
  81
+   # Return true if the branch exists
  82
+   def self.branch_exists(branch)
  83
+      # show-ref --verify returns a fatal exception if the branch doesn't exist
  84
+      return !(`git show-ref --verify \"refs/heads/#{branch}\" 2>&1`.include? "fatal")
  85
+   end
  86
+
81 87
    def self.run_safe(command)
82 88
       puts "> #{command}"
83 89
       result = system(command)
@@ -148,7 +154,7 @@ def self.stashes
148 154
 
149 155
    def self.switch_branch(branch)
150 156
       self.run_safe("git checkout \"#{branch}\"")
151  
-      self.init_submodules
  157
+      self.submodules_update
152 158
       self.run_safe("git clean -ffd") if ARGV.include?('--clean')
153 159
 
154 160
       self.show_stashes_saved_on(branch)
@@ -160,20 +166,6 @@ def self.branch_config(branch)
160 166
       Git::run_safe("git config branch.#{branch}.rebase true")
161 167
    end
162 168
 
163  
-   def self.init_submodules
164  
-      # capture only the path, not the newline
165  
-      basedir = `git rev-parse --show-toplevel`.split("\n").first
166  
-
167  
-      # change directory to base dir
168  
-      Dir.chdir(basedir)
169  
-
170  
-      self.run_safe("git checkout \"#{branch}\"")
171  
-      self.submodules_update
172  
-      self.run_safe("git clean -ffd") if ARGV.include?('--clean')
173  
-
174  
-      self.show_stashes_saved_on(branch)
175  
-   end
176  
-
177 169
    def self.submodules_update
178 170
       # capture only the path, not the newline
179 171
       basedir = `git rev-parse --show-toplevel`.split("\n").first
7  lib/helpers.rb
@@ -18,6 +18,7 @@ def display_feature_help(command = nil, message = nil)
18 18
          :finish  => "feature finish name-of-feature",
19 19
          :merge   => "feature merge [name-of-feature]",
20 20
          :pull    => "feature pull",
  21
+         :pluck   => "feature pluck name-of-feature SHA[...SHA]",
21 22
          :status  => "feature status",
22 23
          :stashes => "feature stashes [-v]",
23 24
          :clean   => "feature clean [--all]",
@@ -93,14 +94,14 @@ def require_argument(program, command = nil, min = 2, max = 2)
93 94
    end
94 95
 
95 96
    if (ARGV.length > max)
96  
-      help.call "Too many arguments. This command accepts only one argument."
  97
+      help.call "Too many arguments. This command accepts only #{max-1} argument."
97 98
    end
98 99
 
99 100
    if (ARGV.length < min)
100  
-      help.call "Missing argument. This command requires exactly one argument."
  101
+      help.call "Missing argument. This command requires exactly #{min-1} argument."
101 102
    end
102 103
 
103  
-   if (ARGV.last !~ /^[a-zA-z0-9-]+$/)
  104
+   if (ARGV[1] !~ /^[a-zA-Z0-9-]+$/)
104 105
       help.call "Invalid branch name: '#{ARGV.last}'"
105 106
    end
106 107
 end

0 notes on commit 87ee558

Please sign in to comment.
Something went wrong with that request. Please try again.