Skip to content

Commit

Permalink
Add support for git-worktree
Browse files Browse the repository at this point in the history
Main reason we didn't previously support work trees was because we had
assumed that the `.git` directory was always located in the repository
root. With separate work trees, this is not necessarily the case.

Add support by using Git commands to fetch the location of the GIT_DIR
instead of trying to determine it ourself.
  • Loading branch information
sds committed Feb 18, 2018
1 parent ea3907a commit 10c2080
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 51 deletions.
7 changes: 0 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,6 @@ This project aims to support the following Ruby runtimes on both \*nix and Windo

* MRI 2.x

## Limitations

Overcommit does not currently support
[`git-worktree`](https://git-scm.com/docs/git-worktree) (introduced in Git 2.5),
but there is an [open issue](https://github.com/brigade/overcommit/issues/336)
tracking progress on adding support.

### Dependencies

Some of the hooks have third-party dependencies. For example, to lint your
Expand Down
2 changes: 1 addition & 1 deletion lib/overcommit/git_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def comment_character
def hooks_path
path = `git config --get core.hooksPath`.chomp
return File.join(Overcommit::Utils.git_dir, 'hooks') if path.empty?
File.absolute_path(path)
File.absolute_path(path, Dir.pwd)
end
end
end
35 changes: 13 additions & 22 deletions lib/overcommit/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,38 +43,29 @@ def script_path(script)
def repo_root
@repo_root ||=
begin
git_dir = Pathname.new(File.expand_path('.')).enum_for(:ascend).find do |path|
File.exist?(File.join(path, '.git'))
result = execute(%w[git rev-parse --show-toplevel])
unless result.success?
raise Overcommit::Exceptions::InvalidGitRepo,
'Unable to determine location of GIT_DIR. ' \
'Not a recognizable Git repository!'
end

unless git_dir
raise Overcommit::Exceptions::InvalidGitRepo, 'no .git directory found'
end

git_dir.to_s
result.stdout.chomp("\n")
end
end

# Returns an absolute path to the .git directory for a repo.
#
# @param repo_dir [String] root directory of git repo
# @return [String]
def git_dir(repo_dir = repo_root)
def git_dir
@git_dir ||=
begin
git_dir = File.expand_path('.git', repo_dir)

# .git could also be a file that contains the location of the git directory
unless File.directory?(git_dir)
git_dir = File.read(git_dir)[/^gitdir: (.*)$/, 1]

# Resolve relative paths
unless git_dir.start_with?('/')
git_dir = File.expand_path(git_dir, repo_dir)
end
result = execute(%w[git rev-parse --git-common-dir])
unless result.success?
raise Overcommit::Exceptions::InvalidGitRepo,
'Unable to determine location of GIT_DIR. ' \
'Not a recognizable Git repository!'
end

git_dir
File.expand_path(result.stdout.chomp("\n"), Dir.pwd)
end
end

Expand Down
26 changes: 6 additions & 20 deletions spec/overcommit/utils_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,27 +52,13 @@
end
end

context 'when .git is a file' do
before do
FileUtils.rm_rf('.git', secure: true)
echo("gitdir: #{git_dir_path}", '.git')
end
context 'when .git directory is not located in the repository' do
let(:git_dir) { Dir.mktmpdir }
let(:repo_dir) { repo(git_dir: git_dir) }

context 'and is a relative path' do
let(:git_dir_path) { '../.git' }

it 'returns the path contained in the file' do
# realpath is so spec passes on Mac OS X
subject.should == File.join(File.realpath(File.dirname(repo_dir)), '.git')
end
end

context 'and is an absolute path' do
let(:git_dir_path) { '/some/arbitrary/path/.git' }

it 'returns the path contained in the file' do
subject.should == git_dir_path
end
it 'returns the path of the external Git directory' do
# realpath is so spec passes on Mac OS X
subject.should == File.realpath(git_dir)
end
end
end
Expand Down
7 changes: 6 additions & 1 deletion spec/support/git_spec_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ module GitSpecHelpers
# @return [String] path of the repository
def repo(options = {})
directory('some-repo') do
`git init --template="#{options[:template_dir]}"`
create_cmd = %w[git init]
create_cmd += ['--template', options[:template_dir]] if options[:template_dir]
create_cmd += ['--separate-git-dir', options[:git_dir]] if options[:git_dir]

result = Overcommit::Utils.execute(create_cmd)
raise "Unable to create repo: #{result.stderr}" unless result.success?

# Need to define user info since some CI contexts don't have defaults set
`git config --local user.name "Overcommit Tester"`
Expand Down

0 comments on commit 10c2080

Please sign in to comment.