Skip to content

Commit 64924f2

Browse files
committed
Add WorkingCopy::merge() to support git merge (#118)
Mirrors the existing checkout() method: accepts a Commit, Reference or string revision, plus optional extra CLI args (e.g. ['--no-ff']).
1 parent 3f177c4 commit 64924f2

3 files changed

Lines changed: 65 additions & 0 deletions

File tree

doc/workingcopy.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,24 @@ $wc->checkout('origin/master', 'master');
2626

2727
You can also pass a *Reference* or a *Commit*.
2828

29+
Merge a revision
30+
----------------
31+
32+
You can merge any revision into the current branch using the *merge* method.
33+
A second argument can be used to pass extra options to the underlying
34+
`git merge` command:
35+
36+
```php
37+
// git merge origin/develop
38+
$wc->merge('origin/develop');
39+
40+
// git merge --no-ff origin/develop
41+
$wc->merge('origin/develop', ['--no-ff']);
42+
```
43+
44+
You can also pass a *Reference* or a *Commit*. A `RuntimeException` is thrown
45+
if the merge fails (for instance because of a conflict).
46+
2947
Staged modifications
3048
--------------------
3149

src/Gitonomy/Git/WorkingCopy.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,29 @@ public function checkout($revision, ?string $branch = null): static
101101
return $this;
102102
}
103103

104+
/**
105+
* Merges a revision into the current branch.
106+
*
107+
* @param Commit|Reference|string $revision
108+
* @param string[] $args extra arguments for the merge command (e.g. ``['--no-ff']``)
109+
*/
110+
public function merge($revision, array $args = []): static
111+
{
112+
if ($revision instanceof Commit) {
113+
$args[] = $revision->getHash();
114+
} elseif ($revision instanceof Reference) {
115+
$args[] = $revision->getFullname();
116+
} elseif (\is_string($revision)) {
117+
$args[] = $revision;
118+
} else {
119+
throw new InvalidArgumentException(\sprintf('Unknown type "%s"', \gettype($revision)));
120+
}
121+
122+
$this->run('merge', $args);
123+
124+
return $this;
125+
}
126+
104127
private function run(string $command, array $args = []): ?string
105128
{
106129
return $this->repository->run($command, $args);

tests/Gitonomy/Git/Tests/WorkingCopyTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,28 @@ public function testGetUntracked(): void
110110

111111
$this->assertContains('untracked.txt', $wc->getUntrackedFiles());
112112
}
113+
114+
public function testMerge(): void
115+
{
116+
$repository = self::createFoobarRepository(false);
117+
$wc = $repository->getWorkingCopy();
118+
$wc->checkout('master');
119+
120+
$wc->merge('origin/diff-features');
121+
122+
$head = $repository->getHeadCommit();
123+
$this->assertCount(2, $head->getParents(), 'Merge produced a merge commit');
124+
$this->assertFileExists($repository->getWorkingDir().'/script_A.php');
125+
}
126+
127+
public function testMergeConflict(): void
128+
{
129+
$this->expectException(RuntimeException::class);
130+
131+
$repository = self::createFoobarRepository(false);
132+
$wc = $repository->getWorkingCopy();
133+
$wc->checkout('master');
134+
135+
$wc->merge('origin/new-feature');
136+
}
113137
}

0 commit comments

Comments
 (0)