Skip to content

Commit a46097f

Browse files
authored
Merge pull request BrainMaestro#83 from BrainMaestro/resolve-git-dir-correctly
Resolve git dir correctly to support worktrees
2 parents b56045c + 07d5b3f commit a46097f

10 files changed

+82
-19
lines changed

.travis.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ matrix:
1111
fast_finish: true
1212

1313
cache:
14-
directories:
15-
- $HOME/.composer/cache
14+
directories:
15+
- $HOME/.composer/cache
1616

1717
before_install:
18-
- phpenv config-rm xdebug.ini || return 0
19-
- travis_retry composer self-update
18+
- phpenv config-rm xdebug.ini || return 0
19+
- travis_retry composer self-update
2020

2121
install:
22-
- travis_retry composer update --no-interaction $IGNORE_PLATFORM_REQS
22+
- travis_retry composer update --no-interaction $IGNORE_PLATFORM_REQS
2323

2424
script:
25-
- composer validate --strict --no-check-lock
26-
- composer check-style
27-
- composer test
25+
- composer validate --strict --no-check-lock
26+
- composer check-style
27+
- composer test

src/Commands/AddCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ protected function configure()
2929
->addOption('no-lock', 'l', InputOption::VALUE_NONE, 'Do not create a lock file')
3030
->addOption('force-setup', null, InputOption::VALUE_NONE, 'Setup hooks even if composer is running with --no-dev')
3131
->addOption('ignore-lock', 'i', InputOption::VALUE_NONE, 'Add the lock file to .gitignore')
32-
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', '.git')
32+
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', absolute_git_dir())
3333
->addOption('force-win', null, InputOption::VALUE_NONE, 'Force windows bash compatibility')
3434
->addOption('global', null, InputOption::VALUE_NONE, 'Add global git hooks')
3535
;

src/Commands/Command.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ final protected function execute(InputInterface $input, OutputInterface $output)
2828
$this->global = $input->getOption('global');
2929
$this->lockFile = Hook::LOCK_FILE;
3030
$this->dir = trim(
31-
$this->global && $this->gitDir === '.git'
31+
$this->global && $this->gitDir === absolute_git_dir()
3232
? dirname(global_hook_dir())
3333
: $this->gitDir
3434
);

src/Commands/ListCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ protected function configure()
1616
->setName('list-hooks')
1717
->setDescription('List added hooks')
1818
->setHelp('This command allows you to list your git hooks')
19-
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', '.git')
19+
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', absolute_git_dir())
2020
->addOption('global', null, InputOption::VALUE_NONE, 'Perform hook command globally for every git repository')
2121
;
2222
}

src/Commands/RemoveCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ protected function configure()
3232
InputOption::VALUE_NONE,
3333
'Delete hooks without checking the lock file'
3434
)
35-
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', '.git')
35+
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', absolute_git_dir())
3636
->addOption('global', null, InputOption::VALUE_NONE, 'Remove global git hooks')
3737
;
3838
}

src/Commands/UpdateCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ protected function configure()
1717
->setDescription('Update git hooks specified in the composer config')
1818
->setHelp('This command allows you to update git hooks')
1919
->addOption('force-setup', null, InputOption::VALUE_NONE, 'Setup hooks even if composer is running with --no-dev')
20-
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', '.git')
20+
->addOption('git-dir', 'g', InputOption::VALUE_REQUIRED, 'Path to git directory', absolute_git_dir())
2121
->addOption('force-win', null, InputOption::VALUE_NONE, 'Force windows bash compatibility')
2222
->addOption('global', null, InputOption::VALUE_NONE, 'Update global git hooks')
2323
;

src/helpers.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,14 @@ function is_composer_dev_mode()
5454
return getenv('COMPOSER_DEV_MODE') === '1';
5555
}
5656
}
57+
58+
if (! function_exists('absolute_git_dir')) {
59+
/**
60+
* Resolve absolute git dir which will serve as the default git dir
61+
* if one is not provided by the user.
62+
*/
63+
function absolute_git_dir()
64+
{
65+
return trim(shell_exec('git rev-parse --absolute-git-dir'));
66+
}
67+
}

tests/AddCommandTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,4 +376,27 @@ public function it_fails_if_global_hook_dir_is_missing()
376376
$this->commandTester->getDisplay()
377377
);
378378
}
379+
380+
/**
381+
* @test
382+
*/
383+
public function it_adds_hooks_correctly_in_a_git_worktree()
384+
{
385+
$currentDir = realpath(getcwd());
386+
shell_exec('git branch develop');
387+
mkdir('../worktree-test');
388+
shell_exec('git worktree add -b test ../worktree-test develop');
389+
chdir('../worktree-test');
390+
391+
$this->commandTester->execute([]);
392+
393+
foreach (array_keys(self::$hooks) as $hook) {
394+
$this->assertContains("Added {$hook} hook", $this->commandTester->getDisplay());
395+
$this->assertFileNotExists(".git/hooks/{$hook}");
396+
$this->assertFileExists("{$currentDir}/.git/hooks/{$hook}");
397+
}
398+
399+
chdir($currentDir);
400+
self::rmdir('../worktree-test');
401+
}
379402
}

tests/TestCase.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,36 @@
77

88
abstract class TestCase extends PHPUnitTestCase
99
{
10-
const TEMP_TEST_DIR = 'cghooks-temp';
11-
1210
protected static $hooks = [
1311
'pre-commit' => 'echo before-commit',
1412
'post-commit' => 'echo after-commit',
1513
];
1614

15+
private $tempTestDir;
1716
private $initialGlobalHookDir;
1817

1918
final public function setUp()
2019
{
2120
$this->initialGlobalHookDir = global_hook_dir();
21+
$this->tempTestDir = 'cghooks-temp-' . bin2hex(random_bytes(5));
22+
23+
mkdir($this->tempTestDir);
24+
chdir($this->tempTestDir);
25+
shell_exec('git init');
26+
shell_exec('git config user.email "[email protected]"');
27+
shell_exec('git config user.name "Composer Git Hooks"');
2228

23-
mkdir(self::TEMP_TEST_DIR);
24-
chdir(self::TEMP_TEST_DIR);
2529
touch('.gitignore');
2630
self::createTestComposerFile();
31+
shell_exec('git add . && git commit -m "Initial commit"');
2732

2833
$this->init();
2934
}
3035

3136
final public function tearDown()
3237
{
3338
chdir('..');
34-
self::rmdir(self::TEMP_TEST_DIR);
39+
self::rmdir($this->tempTestDir);
3540
$this->restoreGlobalHookDir();
3641
putenv('COMPOSER_DEV_MODE=');
3742
}
@@ -81,7 +86,7 @@ public static function removeTestComposerFile($dir = '.')
8186
*
8287
* @param $dir string
8388
*/
84-
private static function rmdir($dir)
89+
public static function rmdir($dir)
8590
{
8691
if (is_dir($dir)) {
8792
$entries = scandir($dir);

tests/UpdateCommandTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,28 @@ public function it_fails_if_global_hook_dir_is_missing()
205205
$this->commandTester->getDisplay()
206206
);
207207
}
208+
209+
/**
210+
* @test
211+
*/
212+
public function it_updates_hooks_correctly_in_a_git_worktree()
213+
{
214+
self::createHooks();
215+
$currentDir = realpath(getcwd());
216+
shell_exec('git branch develop');
217+
mkdir('../worktree-test');
218+
shell_exec('git worktree add -b test ../worktree-test develop');
219+
chdir('../worktree-test');
220+
221+
$this->commandTester->execute([]);
222+
223+
foreach (array_keys(self::$hooks) as $hook) {
224+
$this->assertContains("Updated {$hook} hook", $this->commandTester->getDisplay());
225+
$this->assertFileNotExists(".git/hooks/{$hook}");
226+
$this->assertFileExists("{$currentDir}/.git/hooks/{$hook}");
227+
}
228+
229+
chdir($currentDir);
230+
self::rmdir('../worktree-test');
231+
}
208232
}

0 commit comments

Comments
 (0)