git-fast-forward 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,42 @@
1
+ git fast-forward
2
+ ================
3
+
4
+ `git fast-forward` is a git command which fast-forwards a branch to another commit. It works just like merge, except that it never produces a merge commit. Thus, it only works when you're fast-forwarding to a commit that's a descendent of the current branch.
5
+
6
+ Workflow
7
+ --------
8
+
9
+ Here's how my team usually works:
10
+
11
+ master$ git pull --rebase
12
+ master$ git checkout -b new-feature
13
+ new-feature$ touch lib/new_code.rb
14
+ new-feature$ git add lib/new_code.rb
15
+ new-feature$ git commit -m "Implement awesome new feature."
16
+
17
+ [meanwhile, other people have pushed new code to master...]
18
+
19
+ new-feature$ git fetch
20
+ new-feature$ git rebase origin/master
21
+ new-feature$ git checkout master
22
+ master$ git merge new-feature ### <--- The problem.
23
+ master$ git push
24
+
25
+ This usually works fine, but the last part always bugs me. We rebase to keep a linear history---that's how we like it, as much as possible. But we use the merge command, which, if things aren't rebased quite right, will make a merge commit, which is exactly what we don't want. Usually, we won't notice it until it's pushed. Doesn't happen a lot, but enough to write a better tool.
26
+
27
+
28
+ Usage
29
+ -----
30
+
31
+ It's pretty straightforward:
32
+
33
+ $ gem install git-fast-forward # or whatever
34
+ $ git fast-forward <commit>
35
+
36
+ where `<commit>` is probably a topic branch you've just rebased. If the commit isn't a descendent of your current commit (and therefore not eligible for fast-forwarding), you'll get a nice error message and that's that. Otherwise, it'll fast forward just like `merge`. In fact, it even *calls* `merge`. So you'll get all that nice output.
37
+
38
+
39
+ Bugs, Requests, and Contributions
40
+ ---------------------------------
41
+
42
+ This thing's pretty darn simple. If you'd like it to do something it doesn't, feel free to [add an issue](http://github.com/Peeja/git-fast-forward/issues). Same goes for bugs. Patches and pull requests are certainly welcome.
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ destination = ARGV[0]
4
+
5
+ destination_is_a_descendent_of_head = (`git merge-base HEAD #{destination}` == `git rev-parse HEAD`)
6
+
7
+ if destination_is_a_descendent_of_head
8
+ system("git merge #{destination}")
9
+ else
10
+ $stderr.puts("#{destination} is not a descendent of the current branch. Refusing to fast-forward.")
11
+ exit 1
12
+ end
@@ -0,0 +1 @@
1
+ # Nothing to see here. Just keeps rubygems happy.
@@ -0,0 +1,93 @@
1
+ require 'spec'
2
+
3
+ ENV['PATH'] = "#{File.dirname(__FILE__) + '/../bin'}:#{ENV['PATH']}"
4
+
5
+ describe "git fast-forward" do
6
+ before do
7
+ system <<-SH
8
+ rm -rf test-repo
9
+ mkdir test-repo
10
+ cd test-repo
11
+ git init
12
+ SH
13
+ end
14
+
15
+ after do
16
+ system <<-SH
17
+ rm -rf test-repo
18
+ SH
19
+ end
20
+
21
+ def run(commands)
22
+ commands.split("\n").each do |command|
23
+ command = command.strip
24
+ next if command.empty?
25
+ puts
26
+ puts ">> #{command}"
27
+ system "cd test-repo && #{command}"
28
+ end
29
+ end
30
+
31
+ def commit_named(commit_name)
32
+ `cd test-repo && git rev-parse --revs-only #{commit_name}`
33
+ end
34
+
35
+ context "the given commit is a descendent of the current branch" do
36
+ before do
37
+ run <<-SH
38
+ touch initial-file
39
+ git add initial-file
40
+ git commit -m "Initial commit."
41
+ git branch parent-branch
42
+ git checkout -b descendent-branch
43
+ touch new-file
44
+ git add new-file
45
+ git commit -m "Adding new-file."
46
+ SH
47
+ end
48
+
49
+ it "sets the current branch to the descendent commit" do
50
+ descendent_commit = commit_named("descendent-branch")
51
+
52
+ run <<-SH
53
+ git checkout parent-branch
54
+ git fast-forward descendent-branch
55
+ SH
56
+
57
+ commit_named("parent-branch").should == descendent_commit
58
+ end
59
+ end
60
+
61
+ context "the given commit is not a descendent of the current branch" do
62
+ before do
63
+ run <<-SH
64
+ touch initial-file
65
+ git add initial-file
66
+ git commit -m "Initial commit."
67
+ git checkout -b first-branch
68
+
69
+ git branch other-branch
70
+ touch second-file
71
+ git add second-file
72
+ git commit -m "Second commit."
73
+
74
+ git checkout other-branch
75
+ touch new-file
76
+ git add new-file
77
+ git commit -m "Adding new-file."
78
+ SH
79
+ end
80
+
81
+ it "exists with a status of 1 and leaves the branch where it is" do
82
+ first_branch_before_ff = commit_named("first-branch")
83
+
84
+ run <<-SH
85
+ git checkout first-branch
86
+ git fast-forward other-branch
87
+ SH
88
+
89
+ $?.exitstatus.should == 1
90
+ commit_named("first-branch").should == first_branch_before_ff
91
+ end
92
+ end
93
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git-fast-forward
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 0
9
+ version: 0.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Peter Jaros
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-10-02 00:00:00 -04:00
18
+ default_executable: git-fast-forward
19
+ dependencies: []
20
+
21
+ description: Git command that works like merge, but never creates a merge commit.
22
+ email: peter.a.jaros@gmail.com
23
+ executables:
24
+ - git-fast-forward
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README.markdown
29
+ files:
30
+ - bin/git-fast-forward
31
+ - lib/git-fast-forward.rb
32
+ - README.markdown
33
+ has_rdoc: true
34
+ homepage: http://github.com/Peeja/git-fast-forward
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options:
39
+ - --charset=UTF-8
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.3.6
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Git command that works like merge, but never creates a merge commit.
63
+ test_files:
64
+ - spec/git-fast-forward_spec.rb