diff --git a/lib/git/base.rb b/lib/git/base.rb index 93dcf16e..90575e74 100644 --- a/lib/git/base.rb +++ b/lib/git/base.rb @@ -409,14 +409,27 @@ def each_conflict(&block) # :yields: file, your_version, their_version self.lib.conflicts(&block) end - # pulls the given branch from the given remote into the current branch - # - # @git.pull # pulls from origin/master - # @git.pull('upstream') # pulls from upstream/master - # @git.pull('upstream', 'develope') # pulls from upstream/develop - # - def pull(remote = nil, branch = nil) - self.lib.pull(remote, branch) + # Pulls the given branch from the given remote into the current branch + # + # @param remote [String] the remote repository to pull from + # @param branch [String] the branch to pull from + # @param opts [Hash] options to pass to the pull command + # + # @option opts [Boolean] :allow_unrelated_histories (false) Merges histories of two projects that started their + # lives independently + # @example pulls from origin/master + # @git.pull + # @example pulls from upstream/master + # @git.pull('upstream') + # @example pulls from upstream/develop + # @git.pull('upstream', 'develop') + # + # @return [Void] + # + # @raise [Git::FailedError] if the pull fails + # @raise [ArgumentError] if a branch is given without a remote + def pull(remote = nil, branch = nil, opts = {}) + self.lib.pull(remote, branch, opts) end # returns an array of Git:Remote objects diff --git a/lib/git/lib.rb b/lib/git/lib.rb index da68d83f..28c32b63 100644 --- a/lib/git/lib.rb +++ b/lib/git/lib.rb @@ -1006,10 +1006,11 @@ def push(remote = nil, branch = nil, opts = nil) end end - def pull(remote = nil, branch = nil) + def pull(remote = nil, branch = nil, opts = {}) raise ArgumentError, "You must specify a remote if a branch is specified" if remote.nil? && !branch.nil? arr_opts = [] + arr_opts << '--allow-unrelated-histories' if opts[:allow_unrelated_histories] arr_opts << remote if remote arr_opts << branch if branch command('pull', *arr_opts) diff --git a/tests/units/test_pull.rb b/tests/units/test_pull.rb index 25657f9a..f9a514ab 100644 --- a/tests/units/test_pull.rb +++ b/tests/units/test_pull.rb @@ -3,7 +3,7 @@ class TestPull < Test::Unit::TestCase test 'pull with branch only should raise an ArgumentError' do - in_temp_dir do |path| + in_temp_dir do Dir.mkdir('remote') Dir.chdir('remote') do @@ -23,7 +23,7 @@ class TestPull < Test::Unit::TestCase end test 'pull with no args should use the default remote and current branch name' do - in_temp_dir do |path| + in_temp_dir do Dir.mkdir('remote') Dir.chdir('remote') do @@ -51,7 +51,7 @@ class TestPull < Test::Unit::TestCase end test 'pull with one arg should use arg as remote and the current branch name' do - in_temp_dir do |path| + in_temp_dir do Dir.mkdir('remote') Dir.chdir('remote') do @@ -79,7 +79,7 @@ class TestPull < Test::Unit::TestCase end test 'pull with both remote and branch should use both' do - in_temp_dir do |path| + in_temp_dir do Dir.mkdir('remote') Dir.chdir('remote') do @@ -109,4 +109,31 @@ class TestPull < Test::Unit::TestCase end end end + + test 'when pull fails a Git::FailedError should be raised' do + in_temp_dir do + Dir.mkdir('remote') + + Dir.chdir('remote') do + `git init --initial-branch=master` + File.write('README.md', 'Line 1') + `git add README.md` + `git commit -m "Initial commit"` + end + + `git clone remote/.git local 2>&1` + + Dir.chdir('local') do + git = Git.open('.') + assert_raises(Git::FailedError) { git.pull('origin', 'none_existing_branch') } + end + end + end + + test 'pull with allow_unrelated_histories: true' do + expected_command_line = ['pull', '--allow-unrelated-histories', 'origin', 'feature1', {}] + assert_command_line_eq(expected_command_line) do |git| + git.pull('origin', 'feature1', allow_unrelated_histories: true) + end + end end