require 'fwtoolkit/git_client' require 'tmpdir' describe GitClient do before do @project_folder = Dir.mktmpdir @repo = GitClient::Repository.new @project_folder raise "Can't create temp folder" unless @project_folder end after do FileUtils.rm_rf(@project_folder) end it "initialize and empty repository on an new folder" do @repo.init File.exists?(File.join(@project_folder, '.git')).should be_true end it "fails to initialise a repository on a folder containing a git repo" do Dir.mkdir File.join(@project_folder, '.git') expect { @repo.init }.to raise_error(GitClient::GitError) end it "correctly identify if a folder contains a git repository" do @repo.initialized?.should be_false Dir.mkdir File.join(@project_folder, '.git') @repo.initialized?.should be_true end it "identifies the current branch" do create_sample_repo @repo.current_branch.should == 'master' end it "identifies existing and non existing branches" do create_sample_repo @repo.branch_exist?('master').should be_true @repo.branch_exist?('deleted-branch').should be_false end it "switches to an existing different branch" do create_sample_repo @repo.switch_branch 'test1' @repo.current_branch.should == 'test1' end it "switches to a new branch creating it" do create_sample_repo @repo.switch_branch 'test-new' @repo.current_branch.should == 'test-new' end it "complains when switching to a non existent branch" do create_empty_repo expect { @repo.switch_branch 'fake_branch', false }.to raise_error GitClient::GitError end it "identifies a clean working directory" do create_empty_repo @repo.workdir_clean?.should == true FileUtils.cd(@project_folder) { FileUtils.touch 'new_file.c' } @repo.workdir_clean?.should == false end it "identifies untracked files" do create_sample_repo @repo.status[:untracked].include?('untracked.c').should be_true end it "identifies not up to date files on the index" do create_sample_repo change_the_file 'added.c' @repo.status[:idx_not_up_to_date].include?('added.c').should be_true end it "identifies files added to the index" do create_sample_repo @repo.status[:idx_added].include?('added.c').should be_true end it "identifies files modified on the index" do create_sample_repo change_the_file 'added_and_committed.c' add_the_file 'added_and_committed.c' @repo.status[:idx_modified].include?('added_and_committed.c').should be_true end it "identifies files deleted on the index" do create_sample_repo remove_committed_file_from_git @repo.status[:idx_deleted].include?('added_and_committed.c').should be_true end it "identifies files renamed on the index" do create_sample_repo move_committed_file @repo.status[:idx_renamed].include?('added_and_committed.c').should be_true end it "adds files to the index" do create_sample_repo FileUtils.cd(@project_folder) { FileUtils.touch 'new_file.c' } @repo.add_files_to_index 'new_file.c' tracked_file = false FileUtils.cd(@project_folder) { `git ls-files new_file.c --error-unmatch`; tracked_file = $?.success? } tracked_file.should be_true end it "list all remotes when they exist" do create_sample_repo remotes = @repo.remotes remotes[:origin].should eq 'git@github.com:/Company/repo.git' remotes[:upstream].should eq 'git@github.com:/Company/cool-repo.git' end it "returns an empty remote list when none exists" do create_empty_repo @repo.remotes.should be_empty end it "list all submodules when they exists" do create_repo_with_submodules submodules = @repo.submodules submodules['my_module'].should eq 'git://github.com/dummy_user/my_module.git' submodules['sub/my_module2'].should eq 'git://github.com/dummy_user/my_module2.git' end it "returns an empty submodules list when none exists" do create_empty_repo @repo.submodules.should be_empty end it "commits to the repository" do create_sample_repo commit_hash = @repo.commit "My commit message" valid_commit?(commit_hash).should be_true end it "merges into the current branch" do create_mergable_repo file_exists_in_repo?('test1_file.c').should be_false @repo.merge('test1') file_exists_in_repo?('test1_file.c').should be_true last_commit_merge?.should be_true end it "merges into a specific branch" do create_mergable_repo file_exists_in_repo?('test1_file.c').should be_false @repo.merge('test1', 'test2') last_commit_merge?.should be_true @repo.current_branch.should eq "test2" file_exists_in_repo?('test1_file.c').should be_true end it "complains when trying to merge from a non existing branch" do create_mergable_repo expect { @repo.merge 'fake_branch' }.to raise_error GitClient::GitError end it "complains when trying to merge into a non existing branch" do create_mergable_repo expect { @repo.merge 'test1', 'fake_branch' }.to raise_error GitClient::GitError end it "rebases into the current branch" do create_mergable_repo file_exists_in_repo?('test1_file.c').should be_false @repo.rebase('test1') file_exists_in_repo?('test1_file.c').should be_true end it "rebases into a specific branch" do create_mergable_repo file_exists_in_repo?('test1_file.c').should be_false @repo.rebase('test1', 'test2') @repo.current_branch.should eq "test2" file_exists_in_repo?('test1_file.c').should be_true end it "complains when trying to rebase from a non existing branch" do create_mergable_repo expect { @repo.rebase 'fake_branch' }.to raise_error GitClient::GitError end it "complains when trying to rebase into a non existing branch" do create_mergable_repo expect { @repo.rebase 'test1', 'fake_branch' }.to raise_error GitClient::GitError end it "saves the stash" do create_sample_repo add_the_file 'untracked.c' @repo.save_stash @repo.status.should be_empty end it "pops a stash" do create_repo_with_stashed_data @repo.workdir_clean?.should be_true @repo.pop_stash @repo.workdir_clean?.should be_false end private def create_empty_repo FileUtils.cd(@project_folder) do `git init` end end def create_sample_repo create_empty_repo FileUtils.cd(@project_folder) do write_content_to_file 'added_and_committed.c', '//my c line' write_content_to_file 'added.c', '//my c line new' write_content_to_file 'untracked.c', '//my c line untracked' `git add added_and_committed.c` `git commit -m"My first commit"` `git add added.c` `git branch test1` `git branch test2` `git remote add origin git@github.com:/Company/repo.git` `git remote add upstream git@github.com:/Company/cool-repo.git` end end def create_repo_with_submodules create_sample_repo write_content_to_file '.gitmodules', <<-GITMODULES [submodule "my_module"] path = my_module url = "git://github.com/dummy_user/my_module.git" [submodule "my_module2"] path = sub/my_module2 url = "git://github.com/dummy_user/my_module2.git" GITMODULES end def create_mergable_repo create_empty_repo FileUtils.cd(@project_folder) do FileUtils.touch('master_file.c') `git add .` `git commit -m"First Commit"` `git checkout -b test1 2>&1` `git branch test2` write_content_to_file 'test1_file.c', '//my c line on test1' `git add test1_file.c` `git commit -m "Test1 branchs commit"` `git checkout master 2>&1` end end def create_repo_with_stashed_data create_sample_repo add_the_file 'untracked.c' FileUtils.cd(@project_folder) do `git stash save` end end def write_content_to_file(filename, content) FileUtils.cd(@project_folder) do File.open(filename, 'w') {|f| f.write(content) } end end def change_the_file(filename) write_content_to_file(filename,'//another c line') end def add_the_file(filename) FileUtils.cd(@project_folder) do `git add #{filename}` end end def remove_committed_file_from_git FileUtils.cd(@project_folder) do `git rm added_and_committed.c` end end def move_committed_file FileUtils.cd(@project_folder) do FileUtils.mv('added_and_committed.c', 'moved.c') `git rm added_and_committed.c` `git add moved.c` end end def valid_commit?(sha1) FileUtils.cd(@project_folder) do `git merge-base #{sha1} master` end $?.success? end def last_commit_merge? last_commit_sha = nil FileUtils.cd(@project_folder) do last_commit_sha = `git rev-list --merges HEAD~1..HEAD` end $?.success? && last_commit_sha && last_commit_sha.length > 0 end def file_exists_in_repo?(filename) File.exists? File.join(@project_folder, filename) end end