Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions lib/overcommit/git_repo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,12 @@ def store_merge_state
# conflict. This is necessary since stashing removes the merge state.
if merge_head != 'MERGE_HEAD'
@merge_head = merge_head

merge_mode_file = Overcommit::Utils.git_path('MERGE_MODE')
@merge_mode = File.open(merge_mode_file).read if File.exist?(merge_mode_file)
end

merge_msg_file = File.expand_path('MERGE_MSG', Overcommit::Utils.git_dir)
merge_msg_file = Overcommit::Utils.git_path('MERGE_MSG')
@merge_msg = File.open(merge_msg_file).read if File.exist?(merge_msg_file)
end

Expand All @@ -182,17 +185,20 @@ def store_cherry_pick_state
# of a merge.
def restore_merge_state
if @merge_head
FileUtils.touch(File.expand_path('MERGE_MODE', Overcommit::Utils.git_dir))
File.open(Overcommit::Utils.git_path('MERGE_MODE'), 'w') do |f|
f.write(@merge_mode || '')
end
@merge_mode = nil

File.open(File.expand_path('MERGE_HEAD', Overcommit::Utils.git_dir), 'w') do |f|
File.open(Overcommit::Utils.git_path('MERGE_HEAD'), 'w') do |f|
f.write(@merge_head)
end
@merge_head = nil
end

if @merge_msg
File.open(File.expand_path('MERGE_MSG', Overcommit::Utils.git_dir), 'w') do |f|
f.write("#{@merge_msg}\n")
File.open(Overcommit::Utils.git_path('MERGE_MSG'), 'w') do |f|
f.write(@merge_msg)
end
@merge_msg = nil
end
Expand All @@ -202,8 +208,7 @@ def restore_merge_state
# of a cherry-pick.
def restore_cherry_pick_state
if @cherry_head
File.open(File.expand_path('CHERRY_PICK_HEAD',
Overcommit::Utils.git_dir), 'w') do |f|
File.open(Overcommit::Utils.git_path('CHERRY_PICK_HEAD'), 'w') do |f|
f.write(@cherry_head)
end
@cherry_head = nil
Expand Down
25 changes: 25 additions & 0 deletions lib/overcommit/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,31 @@ def git_dir
end
end

# Returns an absolute path to a file in the current worktree's Git
# directory.
#
# @param path [String]
# @return [String]
def git_path(path)
cmd = %w[git rev-parse]
if GIT_VERSION < '2.5'
cmd << '--git-dir'
else
cmd += ['--git-path', path]
end

result = execute(cmd)
unless result.success?
raise Overcommit::Exceptions::InvalidGitRepo,
'Unable to determine Git path. ' \
'Not a recognizable Git repository!'
end

resolved_path = result.stdout.chomp("\n")
resolved_path = File.join(resolved_path, path) if GIT_VERSION < '2.5'
File.expand_path(resolved_path, Dir.pwd)
end

# Remove ANSI escape sequences from a string.
#
# This is useful for stripping colorized output from external tools.
Expand Down
52 changes: 52 additions & 0 deletions spec/overcommit/git_repo_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,58 @@
end
end

describe 'operation state in a linked worktree',
if: Overcommit::GIT_VERSION >= '2.5' do
around do |example|
repo do
`git commit --allow-empty -m "Initial commit"`
linked_worktree = File.join(File.dirname(Dir.pwd), 'linked-worktree')
result = Overcommit::Utils.execute(
%W[git worktree add -b linked-worktree #{linked_worktree}],
)
raise "Unable to create worktree: #{result.stderr}" unless result.success?

Dir.chdir(linked_worktree) { example.run }
end
end

let(:git_dir) { File.expand_path(`git rev-parse --git-dir`.chomp) }
let(:common_dir) { File.expand_path(`git rev-parse --git-common-dir`.chomp) }
let(:head) { `git rev-parse HEAD`.chomp }

it 'restores merge state only to the linked worktree' do
merge_message = "Merge linked branch\n"
File.write(File.join(git_dir, 'MERGE_HEAD'), head)
File.write(File.join(git_dir, 'MERGE_MODE'), 'no-ff')
File.write(File.join(git_dir, 'MERGE_MSG'), merge_message)

described_class.store_merge_state
FileUtils.rm(
%w[MERGE_HEAD MERGE_MODE MERGE_MSG].
map { |file| File.join(git_dir, file) },
)
described_class.restore_merge_state

File.read(File.join(git_dir, 'MERGE_HEAD')).should == head
File.read(File.join(git_dir, 'MERGE_MODE')).should == 'no-ff'
File.read(File.join(git_dir, 'MERGE_MSG')).should == merge_message
File.exist?(File.join(common_dir, 'MERGE_HEAD')).should == false
File.exist?(File.join(common_dir, 'MERGE_MODE')).should == false
File.exist?(File.join(common_dir, 'MERGE_MSG')).should == false
end

it 'restores cherry-pick state only to the linked worktree' do
File.write(File.join(git_dir, 'CHERRY_PICK_HEAD'), head)

described_class.store_cherry_pick_state
FileUtils.rm(File.join(git_dir, 'CHERRY_PICK_HEAD'))
described_class.restore_cherry_pick_state

File.read(File.join(git_dir, 'CHERRY_PICK_HEAD')).should == head
File.exist?(File.join(common_dir, 'CHERRY_PICK_HEAD')).should == false
end
end

describe '.staged_submodule_removals' do
subject { described_class.staged_submodule_removals }

Expand Down
Loading