git-fast-forward 0.0.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.
- data/README.markdown +42 -0
- data/bin/git-fast-forward +12 -0
- data/lib/git-fast-forward.rb +1 -0
- data/spec/git-fast-forward_spec.rb +93 -0
- metadata +64 -0
data/README.markdown
ADDED
@@ -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
|