Skip to content

Resolve git dir correctly to support worktrees #83

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 9, 2019
Merged
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
16 changes: 8 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ matrix:
fast_finish: true

cache:
directories:
- $HOME/.composer/cache
directories:
- $HOME/.composer/cache

before_install:
- phpenv config-rm xdebug.ini || return 0
- travis_retry composer self-update
- phpenv config-rm xdebug.ini || return 0
- travis_retry composer self-update

install:
- travis_retry composer update --no-interaction $IGNORE_PLATFORM_REQS
- travis_retry composer update --no-interaction $IGNORE_PLATFORM_REQS

script:
- composer validate --strict --no-check-lock
- composer check-style
- composer test
- composer validate --strict --no-check-lock
- composer check-style
- composer test
2 changes: 1 addition & 1 deletion src/Commands/AddCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ protected function configure()
->addOption('no-lock', 'l', InputOption::VALUE_NONE, 'Do not create a lock file')
->addOption('force-setup', null, InputOption::VALUE_NONE, 'Setup hooks even if composer is running with --no-dev')
->addOption('ignore-lock', 'i', InputOption::VALUE_NONE, 'Add the lock file to .gitignore')
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', '.git')
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', absolute_git_dir())
->addOption('force-win', null, InputOption::VALUE_NONE, 'Force windows bash compatibility')
->addOption('global', null, InputOption::VALUE_NONE, 'Add global git hooks')
;
Expand Down
2 changes: 1 addition & 1 deletion src/Commands/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ final protected function execute(InputInterface $input, OutputInterface $output)
$this->global = $input->getOption('global');
$this->lockFile = Hook::LOCK_FILE;
$this->dir = trim(
$this->global && $this->gitDir === '.git'
$this->global && $this->gitDir === absolute_git_dir()
? dirname(global_hook_dir())
: $this->gitDir
);
Expand Down
2 changes: 1 addition & 1 deletion src/Commands/ListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected function configure()
->setName('list-hooks')
->setDescription('List added hooks')
->setHelp('This command allows you to list your git hooks')
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', '.git')
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', absolute_git_dir())
->addOption('global', null, InputOption::VALUE_NONE, 'Perform hook command globally for every git repository')
;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Commands/RemoveCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected function configure()
InputOption::VALUE_NONE,
'Delete hooks without checking the lock file'
)
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', '.git')
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', absolute_git_dir())
->addOption('global', null, InputOption::VALUE_NONE, 'Remove global git hooks')
;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Commands/UpdateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ protected function configure()
->setDescription('Update git hooks specified in the composer config')
->setHelp('This command allows you to update git hooks')
->addOption('force-setup', null, InputOption::VALUE_NONE, 'Setup hooks even if composer is running with --no-dev')
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', '.git')
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', absolute_git_dir())
->addOption('force-win', null, InputOption::VALUE_NONE, 'Force windows bash compatibility')
->addOption('global', null, InputOption::VALUE_NONE, 'Update global git hooks')
;
Expand Down
11 changes: 11 additions & 0 deletions src/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,14 @@ function is_composer_dev_mode()
return getenv('COMPOSER_DEV_MODE') === '1';
}
}

if (! function_exists('absolute_git_dir')) {
/**
* Resolve absolute git dir which will serve as the default git dir
* if one is not provided by the user.
*/
function absolute_git_dir()
{
return trim(shell_exec('git rev-parse --absolute-git-dir'));
}
}
23 changes: 23 additions & 0 deletions tests/AddCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -376,4 +376,27 @@ public function it_fails_if_global_hook_dir_is_missing()
$this->commandTester->getDisplay()
);
}

/**
* @test
*/
public function it_adds_hooks_correctly_in_a_git_worktree()
{
$currentDir = realpath(getcwd());
shell_exec('git branch develop');
mkdir('../worktree-test');
shell_exec('git worktree add -b test ../worktree-test develop');
chdir('../worktree-test');

$this->commandTester->execute([]);

foreach (array_keys(self::$hooks) as $hook) {
$this->assertContains("Added {$hook} hook", $this->commandTester->getDisplay());
$this->assertFileNotExists(".git/hooks/{$hook}");
$this->assertFileExists("{$currentDir}/.git/hooks/{$hook}");
}

chdir($currentDir);
self::rmdir('../worktree-test');
}
}
17 changes: 11 additions & 6 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,36 @@

abstract class TestCase extends PHPUnitTestCase
{
const TEMP_TEST_DIR = 'cghooks-temp';

protected static $hooks = [
'pre-commit' => 'echo before-commit',
'post-commit' => 'echo after-commit',
];

private $tempTestDir;
private $initialGlobalHookDir;

final public function setUp()
{
$this->initialGlobalHookDir = global_hook_dir();
$this->tempTestDir = 'cghooks-temp-' . bin2hex(random_bytes(5));

mkdir($this->tempTestDir);
chdir($this->tempTestDir);
shell_exec('git init');
shell_exec('git config user.email "[email protected]"');
shell_exec('git config user.name "Composer Git Hooks"');

mkdir(self::TEMP_TEST_DIR);
chdir(self::TEMP_TEST_DIR);
touch('.gitignore');
self::createTestComposerFile();
shell_exec('git add . && git commit -m "Initial commit"');

$this->init();
}

final public function tearDown()
{
chdir('..');
self::rmdir(self::TEMP_TEST_DIR);
self::rmdir($this->tempTestDir);
$this->restoreGlobalHookDir();
putenv('COMPOSER_DEV_MODE=');
}
Expand Down Expand Up @@ -81,7 +86,7 @@ public static function removeTestComposerFile($dir = '.')
*
* @param $dir string
*/
private static function rmdir($dir)
public static function rmdir($dir)
{
if (is_dir($dir)) {
$entries = scandir($dir);
Expand Down
24 changes: 24 additions & 0 deletions tests/UpdateCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,28 @@ public function it_fails_if_global_hook_dir_is_missing()
$this->commandTester->getDisplay()
);
}

/**
* @test
*/
public function it_updates_hooks_correctly_in_a_git_worktree()
{
self::createHooks();
$currentDir = realpath(getcwd());
shell_exec('git branch develop');
mkdir('../worktree-test');
shell_exec('git worktree add -b test ../worktree-test develop');
chdir('../worktree-test');

$this->commandTester->execute([]);

foreach (array_keys(self::$hooks) as $hook) {
$this->assertContains("Updated {$hook} hook", $this->commandTester->getDisplay());
$this->assertFileNotExists(".git/hooks/{$hook}");
$this->assertFileExists("{$currentDir}/.git/hooks/{$hook}");
}

chdir($currentDir);
self::rmdir('../worktree-test');
}
}