diff --git a/doc/repository.md b/doc/repository.md index 05b4a4e..90df60e 100644 --- a/doc/repository.md +++ b/doc/repository.md @@ -145,3 +145,21 @@ It is possible to send environment variables to the `git` commands. ```php $repository = new Gitonomy\Git\Repository('/tmp/foo', ['environment_variables' => ['GIT_']]) ``` + +Pull +---- + +You can pull changes from remote by calling `pull()`: + +```php +$repository->pull(); +``` + +Push +---- + +You can push changes to remote by calling `push()`: + +```php +$repository->push(); +``` diff --git a/doc/workingcopy.md b/doc/workingcopy.md index 4ecea6c..a987896 100644 --- a/doc/workingcopy.md +++ b/doc/workingcopy.md @@ -45,3 +45,43 @@ You can get pending modifications on tracked files by calling method ```php $diff = $wc->getDiffPending(); ``` + +Staging file(s) +--------------- + +You can stage changed files by calling `stage($files)`: + +```php +$wc->stage(['file1.txt', 'file2.txt']); +``` + +Unstaging file(s) +----------------- + +You can unstage files by calling `unstage($files)`: + +```php +$wc->unstage(['file1.txt', 'file2.txt']); +``` + +Discarding file(s) changes +-------------------------- + +You can discard files changed by calling `discard($files)`: + +```php +$wc->discard(['file1.txt', 'file2.txt']); +``` + +Committing +---------- + +You can commit changed files by calling `commit($message, $author, $files)`: + +```php +$wc->commit('summary', 'author', ['file1.txt', 'file2.txt']); +``` + +NOTE :: this will commit all staged files, the `$files` argument simply +stages those files before commiting, if you already have files staged by +having called `stage($files)` these files are included in the commit. diff --git a/src/Gitonomy/Git/Repository.php b/src/Gitonomy/Git/Repository.php index 36e3585..70b634e 100644 --- a/src/Gitonomy/Git/Repository.php +++ b/src/Gitonomy/Git/Repository.php @@ -61,9 +61,9 @@ class Repository protected $referenceBag; /** - * Logger (can be null). + * The logger instance (can be null). * - * @var LoggerInterface + * @var LoggerInterface|null */ protected $logger; @@ -517,8 +517,33 @@ public function setDescription($description) } /** - * This command is a facility command. You can run any command - * directly on git repository. + * Executes pull command. + * + * @return bool True if there was anything to do + */ + public function pull() + { + $result = $this->run('pull'); + + return preg_match('/\d (?:file|files) changed, \d insertion\(\+\), \d deletion\(\-\)/', $result) === 1; + } + + /** + * Executes push command. + * + * @return bool True if there was anything to do + */ + public function push() + { + $result = $this->run('push'); + + return strpos($result, 'Writing objects: 100%') !== false; + } + + /** + * This command is a facility command. + * + * You can run any command directly on the git repository. * * @param string $command Git command to run (checkout, branch, tag) * @param array $args Arguments of git command @@ -581,7 +606,7 @@ public function setLogger(LoggerInterface $logger) /** * Returns repository logger. * - * @return LoggerInterface the logger or null + * @return LoggerInterface|null the logger or null */ public function getLogger() { diff --git a/src/Gitonomy/Git/WorkingCopy.php b/src/Gitonomy/Git/WorkingCopy.php index 057253b..f7aac38 100644 --- a/src/Gitonomy/Git/WorkingCopy.php +++ b/src/Gitonomy/Git/WorkingCopy.php @@ -70,6 +70,13 @@ public function getDiffStaged() } /** + * Checkout the given revision. + * + * Optionally sets the branch. + * + * @param Commit|Reference|string $revision + * @param string|null $branch + * * @return WorkingCopy */ public function checkout($revision, $branch = null) @@ -94,6 +101,78 @@ public function checkout($revision, $branch = null) return $this; } + /** + * Stages the files provided by arguments. + * + * @param string[] $files + * + * @return Repository the current repository + */ + public function stage(array $files = []) + { + foreach ($files as $file) { + $this->run('add', [$file]); + } + + return $this; + } + + /** + * Unstages the files provided by arguments. + * + * @param string[] $files + * + * @return Repository the current repository + */ + public function unstage(array $files = []) + { + foreach ($files as $file) { + $this->run('restore', ['--staged', $file]); + } + + return $this; + } + + /** + * Discards file changed from files provided by arguments. + * + * @param string[] $files + * + * @return Repository the current repository + */ + public function discard(array $files = []) + { + foreach ($files as $file) { + $this->run('checkout', ['--', $file]); + } + + return $this; + } + + /** + * Creates a commit with the message provided. + * + * Optionally stages files provided. + * + * @param string $message + * @param string|null $author + * @param string[] $files + * + * @return Repository the current repository + */ + public function commit($message, $author = null, array $files = []) + { + $this->stage($files); + + if ($author === null) { + $this->run('commit', ['-m', $message]); + } else { + $this->run('commit', ['-m', $message, sprintf('--author="%s"', $author)]); + } + + return $this; + } + protected function run($command, array $args = []) { return $this->repository->run($command, $args); diff --git a/tests/Gitonomy/Git/Tests/RepositoryTest.php b/tests/Gitonomy/Git/Tests/RepositoryTest.php index 6eee0e6..b11cf5b 100644 --- a/tests/Gitonomy/Git/Tests/RepositoryTest.php +++ b/tests/Gitonomy/Git/Tests/RepositoryTest.php @@ -55,6 +55,22 @@ public function testGetDescription($repository) $this->assertSame("Unnamed repository; edit this file 'description' to name the repository.\n", $repository->getDescription()); } + /** + * @dataProvider provideFoobar + */ + public function testPull($repository) + { + $this->assertIsBool($repository->pull()); + } + + /** + * @dataProvider provideFoobar + */ + public function testPush($repository) + { + $this->assertIsBool($repository->push()); + } + /** * @dataProvider provideFoobar */ diff --git a/tests/Gitonomy/Git/Tests/WorkingCopyTest.php b/tests/Gitonomy/Git/Tests/WorkingCopyTest.php index dfa048f..a4956ea 100644 --- a/tests/Gitonomy/Git/Tests/WorkingCopyTest.php +++ b/tests/Gitonomy/Git/Tests/WorkingCopyTest.php @@ -110,4 +110,66 @@ public function testGetUntracked() $this->assertContains('untracked.txt', $wc->getUntrackedFiles()); } + + public function testStage() + { + $repository = self::createFoobarRepository(false); + $wc = $repository->getWorkingCopy(); + + $file = $repository->getWorkingDir().'/test.sh'; + file_put_contents($file, 'test'); + + $this->assertContains('test.sh', $wc->getDiffPending()); + + $wc->stage(['test.sh']); + + $this->assertContains('test.sh', $wc->getDiffStaged()); + } + + public function testUnstage() + { + $repository = self::createFoobarRepository(false); + $wc = $repository->getWorkingCopy(); + + $file = $repository->getWorkingDir().'/test.sh'; + file_put_contents($file, 'test'); + + $wc->stage(['test.sh']); + $this->assertContains('test.sh', $wc->getDiffStaged()); + + $wc->unstage(['test.sh']); + $this->assertContains('test.sh', $wc->getDiffPending()); + } + + public function testDiscard() + { + $repository = self::createFoobarRepository(false); + $wc = $repository->getWorkingCopy(); + + $file = $repository->getWorkingDir().'/test.sh'; + file_put_contents($file, 'test'); + + $this->assertContains('test.sh', $wc->getDiffPending()); + + $wc->discard(['test.sh']); + + $diffPending = $wc->getDiffPending(); + $this->assertCount(0, $diffPending->getFiles()); + } + + public function testCommit() + { + $repository = self::createFoobarRepository(false); + $wc = $repository->getWorkingCopy(); + + $file = $repository->getWorkingDir().'/test.sh'; + file_put_contents($file, 'test'); + + $this->assertContains('test.sh', $wc->getDiffPending()); + + $wc->commit('this is the commit message', 'John Doe', ['test.sh']); + + $diffPending = $wc->getDiffPending(); + $this->assertCount(0, $diffPending->getFiles()); + } }