Completed
Pull Request — develop (#95)
by
unknown
11:07
created

Repository::reset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 2
crap 1
1
<?php
2
/**
3
 * GitElephant - An abstraction layer for git written in PHP
4
 * Copyright (C) 2013  Matteo Giachino
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see [http://www.gnu.org/licenses/].
18
 */
19
20
namespace GitElephant;
21
22
use \GitElephant\Command\FetchCommand;
23
use \GitElephant\Command\PullCommand;
24
use \GitElephant\Command\PushCommand;
25
use \GitElephant\Command\RemoteCommand;
26
use GitElephant\Command\ResetCommand;
27
use \GitElephant\Exception\InvalidRepositoryPathException;
28
use \GitElephant\Command\Caller\Caller;
29
use \GitElephant\Objects\Author;
30
use \GitElephant\Objects\Remote;
31
use \GitElephant\Objects\Tree;
32
use \GitElephant\Objects\Branch;
33
use \GitElephant\Objects\Tag;
34
use \GitElephant\Objects\Object;
35
use \GitElephant\Objects\Diff\Diff;
36
use \GitElephant\Objects\Commit;
37
use \GitElephant\Objects\Log;
38
use \GitElephant\Objects\LogRange;
39
use \GitElephant\Objects\TreeishInterface;
40
use \GitElephant\Command\MainCommand;
41
use \GitElephant\Command\BranchCommand;
42
use \GitElephant\Command\MergeCommand;
43
use \GitElephant\Command\RevParseCommand;
44
use \GitElephant\Command\TagCommand;
45
use \GitElephant\Command\LogCommand;
46
use \GitElephant\Command\CloneCommand;
47
use \GitElephant\Command\CatFileCommand;
48
use \GitElephant\Command\LsTreeCommand;
49
use \GitElephant\Command\SubmoduleCommand;
50
use GitElephant\Objects\TreeObject;
51
use \GitElephant\Status\Status;
52
use \GitElephant\Status\StatusIndex;
53
use \GitElephant\Status\StatusWorkingTree;
54
use \Symfony\Component\Filesystem\Filesystem;
55
use \Symfony\Component\Finder\Finder;
56
use \Symfony\Component\Finder\SplFileInfo;
57
58
/**
59
 * Repository
60
 *
61
 * Base Class for repository operations
62
 *
63
 * @author Matteo Giachino <[email protected]>
64
 * @author Dhaval Patel <[email protected]>
65
 */
66
class Repository
67
{
68
    /**
69
     * the repository path
70
     *
71
     * @var string
72
     */
73
    private $path;
74
75
    /**
76
     * the caller instance
77
     *
78
     * @var \GitElephant\Command\Caller\Caller
79
     */
80
    private $caller;
81
82
    /**
83
     * A general repository name
84
     *
85
     * @var string $name the repository name
86
     */
87
    private $name;
88
89
    /**
90
     * A list of global configs to apply to every command
91
     * 
92
     * @var array
93
     */
94
    private $globalConfigs = array();
95
96
    /**
97
     * A list of global options to apply to every command
98
     * 
99
     * @var array
100
     */
101
    private $globalOptions = array();
102
103
    /**
104
     * A list of global arguments to apply to every command
105
     * 
106
     * @var array
107
     */
108
    private $globalCommandArguments = array();
109
110
    /**
111
     * Class constructor
112
     *
113
     * @param string         $repositoryPath the path of the git repository
114
     * @param GitBinary|null $binary         the GitBinary instance that calls the commands
115
     * @param string         $name           a repository name
116
     *
117
     * @throws Exception\InvalidRepositoryPathException
118 100
     */
119
    public function __construct($repositoryPath, GitBinary $binary = null, $name = null)
120 100
    {
121 100
        if (is_null($binary)) {
122 100
            $binary = new GitBinary();
123
        }
124 100
125 100
        $this->path = $repositoryPath;
126 100
        $this->caller = new Caller($binary, $repositoryPath);
127 100
        $this->name = $name;
128
    }
129
130
    /**
131
     * Factory method
132
     *
133
     * @param string         $repositoryPath the path of the git repository
134
     * @param GitBinary|null $binary         the GitBinary instance that calls the commands
135
     * @param string         $name           a repository name
136
     *
137
     * @return \GitElephant\Repository
138 99
     */
139 1
    public static function open($repositoryPath, GitBinary $binary = null, $name = null)
140 99
    {
141
        return new self($repositoryPath, $binary, $name);
142
    }
143
144
    /**
145
     * create a repository from a remote git url, or a local filesystem
146
     * and save it in a temp folder
147
     *
148
     * @param string|Repository $git            the git remote url, or the filesystem path
149
     * @param null              $repositoryPath path
150
     * @param GitBinary         $binary         binary
151
     * @param null              $name           repository name
152
     *
153
     * @throws \RuntimeException
154
     * @throws \Symfony\Component\Filesystem\Exception\IOException
155
     * @return Repository
156 1
     */
157
    public static function createFromRemote($git, $repositoryPath = null, GitBinary $binary = null, $name = null)
158 1
    {
159 1
        if (null === $repositoryPath) {
160 1
            $tempDir = realpath(sys_get_temp_dir());
161 1
            $repositoryPath = sprintf('%s%s%s', $tempDir, DIRECTORY_SEPARATOR, sha1(uniqid()));
162 1
            $fs = new Filesystem();
163 1
            $fs->mkdir($repositoryPath);
164 1
        }
165 1
        $repository = new Repository($repositoryPath, $binary, $name);
166
        if ($git instanceof Repository) {
167
            $git = $git->getPath();
168 1
        }
169 1
        $repository->cloneFrom($git, $repositoryPath);
0 ignored issues
show
Bug introduced by
It seems like $repositoryPath defined by sprintf('%s%s%s', $tempD...ARATOR, sha1(uniqid())) on line 161 can also be of type string; however, GitElephant\Repository::cloneFrom() does only seem to accept null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
170
        $repository->checkoutAllRemoteBranches();
171 1
172
        return $repository;
173
    }
174
175
    /**
176
     * Init the repository
177
     *
178
     * @param bool $bare created a bare repository
179
     *
180
     * @throws \RuntimeException
181
     * @throws \Symfony\Component\Process\Exception\LogicException
182
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
183
     * @throws \Symfony\Component\Process\Exception\RuntimeException
184
     * @return Repository
185 89
     */
186
    public function init($bare = false)
187 89
    {
188
        $this->caller->execute(MainCommand::getInstance($this)->init($bare));
189 89
190
        return $this;
191
    }
192
193
    /**
194
     * Stage the working tree content
195
     *
196
     * @param string|Object $path the path to store
197
     *
198
     * @throws \RuntimeException
199
     * @throws \Symfony\Component\Process\Exception\LogicException
200
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
201
     * @throws \Symfony\Component\Process\Exception\RuntimeException
202
     * @return Repository
203 85
     */
204
    public function stage($path = '.')
205 85
    {
206
        $this->caller->execute(MainCommand::getInstance($this)->add($path));
0 ignored issues
show
Bug introduced by
It seems like $path defined by parameter $path on line 204 can also be of type object<GitElephant\Objects\Object>; however, GitElephant\Command\MainCommand::add() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
207 85
208
        return $this;
209
    }
210
211
    /**
212
     * Unstage a tree content
213
     *
214
     * @param string|Object $path the path to unstage
215
     *
216
     * @throws \RuntimeException
217
     * @throws \Symfony\Component\Process\Exception\LogicException
218
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
219
     * @throws \Symfony\Component\Process\Exception\RuntimeException
220
     * @return Repository
221 2
     */
222
    public function unstage($path)
223 2
    {
224
        $this->caller->execute(MainCommand::getInstance($this)->unstage($path), true, null, array(0, 1));
0 ignored issues
show
Bug introduced by
It seems like $path defined by parameter $path on line 222 can also be of type object<GitElephant\Objects\Object>; however, GitElephant\Command\MainCommand::unstage() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
225 2
226
        return $this;
227
    }
228
229
    /**
230
     * Move a file/directory
231
     *
232
     * @param string|Object $from source path
233
     * @param string|Object $to   destination path
234
     *
235
     * @throws \RuntimeException
236
     * @throws \Symfony\Component\Process\Exception\LogicException
237
     * @throws \InvalidArgumentException
238
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
239
     * @throws \Symfony\Component\Process\Exception\RuntimeException
240
     * @return Repository
241 1
     */
242
    public function move($from, $to)
243 1
    {
244
        $this->caller->execute(MainCommand::getInstance($this)->move($from, $to));
245 1
246
        return $this;
247
    }
248
249
    /**
250
     * Remove a file/directory
251
     *
252
     * @param string|Object $path      the path to remove
253
     * @param bool          $recursive recurse
254
     * @param bool          $force     force
255
     *
256
     * @throws \RuntimeException
257
     * @throws \Symfony\Component\Process\Exception\LogicException
258
     * @throws \InvalidArgumentException
259
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
260
     * @throws \Symfony\Component\Process\Exception\RuntimeException
261
     * @return Repository
262 1
     */
263
    public function remove($path, $recursive = false, $force = false)
264 1
    {
265
        $this->caller->execute(MainCommand::getInstance($this)->remove($path, $recursive, $force));
266 1
267
        return $this;
268
    }
269
270
    /**
271
     * Commit content to the repository, eventually staging all unstaged content
272
     *
273
     * @param string        $message  the commit message
274
     * @param bool          $stageAll whether to stage on not everything before commit
275
     * @param string|null   $ref      the reference to commit to (checkout -> commit -> checkout previous)
276
     * @param string|Author $author   override the author for this commit
277
     *
278
     * @throws \RuntimeException
279
     * @throws \InvalidArgumentException
280
     * @throws \Symfony\Component\Process\Exception\RuntimeException
281
     * @return Repository
282 82
     */
283
    public function commit($message, $stageAll = false, $ref = null, $author = null, $allowEmpty = false)
284 82
    {
285 82
        $currentBranch = null;
286 1
        if (! is_null($ref)) {
287 1
            $currentBranch = $this->getMainBranch();
288 1
            $this->checkout($ref);
289 82
        }
290 82
        if ($stageAll) {
291 82
            $this->stage();
292 82
        }
293 82
        $this->caller->execute(MainCommand::getInstance($this)->commit($message, $stageAll, $author, $allowEmpty));
294 1
        if (! is_null($ref)) {
295 1
            $this->checkout($currentBranch);
0 ignored issues
show
Bug introduced by
It seems like $currentBranch defined by null on line 285 can be null; however, GitElephant\Repository::checkout() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
296
        }
297 82
298
        return $this;
299
    }
300
301
    /**
302
     * rev-parse command - often used to return a commit tag.
303
     *
304
     * @param array                  $options the options to apply to rev-parse
305
     * @param string|Object|Commit   $arg the argument (may be a branch head, etc)
306
     *
307
     * @throws \RuntimeException
308
     * @throws \InvalidArgumentException
309
     * @throws \Symfony\Component\Process\Exception\RuntimeException
310
     * @return array
311 1
     */
312
    public function revParse($arg = null, Array $options = array())
0 ignored issues
show
Coding Style introduced by
As per coding-style, PHP keywords should be in lowercase; expected array, but found Array.
Loading history...
313 1
    {
314
        $this->caller->execute(RevParseCommand::getInstance()->revParse($arg, $options));
0 ignored issues
show
Bug introduced by
It seems like $arg defined by parameter $arg on line 312 can also be of type object<GitElephant\Objects\Commit> or object<GitElephant\Objects\Object>; however, GitElephant\Command\RevParseCommand::revParse() does only seem to accept object<GitElephant\Objects\Branch>|string|null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
315 1
316
        return array_map('trim', $this->caller->getOutputLines(true));
317
    }
318
319
    /**
320
     * Check if this is a bare repository
321
     * @return boolean
322 1
     */
323
    public function isBare()
324 1
    {
325 1
        $options = array(RevParseCommand::OPTION_IS_BARE_REPOSIORY);
326
        $this->caller->execute(RevParseCommand::getInstance()->revParse(null, $options));
327 1
328
        return trim($this->caller->getOutput()) === 'true';
329
    }
330
331
    /**
332
     * @param TreeishInterface|Commit|string $arg
333
     * @param array $options
334
     */
335 5
    public function reset($arg,$options)
0 ignored issues
show
Coding Style introduced by
Expected 1 space between comma and argument "$options"; 0 found
Loading history...
336
    {
337 5
        $this->caller->execute(ResetCommand::getInstance()->reset($arg,$options));
338
    }
339
340
    /**
341
     * Get the repository status
342
     *
343 1
     * @return Status
344
     */
345 1
    public function getStatus()
346
    {
347
        return Status::get($this);
348
    }
349
350
    /**
351 2
     * @return StatusWorkingTree
352
     */
353 2
    public function getWorkingTreeStatus()
354
    {
355
        return StatusWorkingTree::get($this);
356
    }
357
358
    /**
359
     * @return StatusIndex
360
     */
361
    public function getIndexStatus()
362
    {
363
        return StatusIndex::get($this);
364
    }
365
    
366
    /**
367
     * isClean Return true if the repository is not dirty.
368
     * 
369
     * @return boolean
370
     */
371
    public function isClean()
372
    {
373
        return $this->getStatus()->all()->isEmpty();
374
    }
375
    
376
    /**
377
     * isDirty Return true if the repository has some modified files.
378
     * 
379
     * @return boolean
380
     */
381
    public function isDirty()
382
    {
383
        return !$this->isClean();
384
    }
385 4
386
    /**
387 4
     * Get the repository status as a string
388
     *
389 4
     * @throws \RuntimeException
390
     * @throws \Symfony\Component\Process\Exception\LogicException
391
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
392
     * @throws \Symfony\Component\Process\Exception\RuntimeException
393
     * @return array
394
     */
395
    public function getStatusOutput()
396
    {
397
        $this->caller->execute(MainCommand::getInstance($this)->status());
398
399
        return array_map('trim', $this->caller->getOutputLines());
400
    }
401
402 26
    /**
403
     * Create a new branch
404 26
     *
405
     * @param string $name       the new branch name
406 26
     * @param null   $startPoint the reference to create the branch from
407
     *
408
     * @throws \RuntimeException
409
     * @throws \Symfony\Component\Process\Exception\RuntimeException
410
     * @return Repository
411
     */
412
    public function createBranch($name, $startPoint = null)
413
    {
414
        Branch::create($this, $name, $startPoint);
415
416
        return $this;
417
    }
418
419
    /**
420
     * Delete a branch by its name
421
     * This function change the state of the repository on the filesystem
422 1
     *
423
     * @param string $name  The branch to delete
424 1
     * @param bool   $force Force the delete
425
     *
426 1
     * @throws \RuntimeException
427
     * @throws \Symfony\Component\Process\Exception\LogicException
428
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
429
     * @throws \Symfony\Component\Process\Exception\RuntimeException
430
     * @return Repository
431
     */
432
    public function deleteBranch($name, $force = false)
433
    {
434
        $this->caller->execute(BranchCommand::getInstance($this)->delete($name, $force));
435
436
        return $this;
437
    }
438
439
    /**
440
     * An array of Branch objects
441
     *
442 17
     * @param bool $namesOnly return an array of branch names as a string
443
     * @param bool $all       lists also remote branches
444 17
     *
445 17
     * @throws \RuntimeException
446 6
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
447 6
     * @throws \Symfony\Component\Process\Exception\LogicException
448 6
     * @throws \InvalidArgumentException
449 6
     * @throws \Symfony\Component\Process\Exception\RuntimeException
450
     * @return array
451 6
     */
452 6
    public function getBranches($namesOnly = false, $all = false)
453
    {
454 6
        $branches = array();
455 6
        if ($namesOnly) {
456 14
            $outputLines = $this->caller->execute(
457 14
                BranchCommand::getInstance($this)->listBranches($all, true)
458 14
            )->getOutputLines(true);
459 14
            $branches = array_map(
460 14
                function ($v) {
461 14
                    return ltrim($v, '* ');
462
                },
463
                $outputLines
464 17
            );
465
        } else {
466
            $outputLines = $this->caller->execute(
467
                BranchCommand::getInstance($this)->listBranches($all)
468
            )->getOutputLines(true);
469
            foreach ($outputLines as $branchLine) {
470
                $branches[] = Branch::createFromOutputLine($this, $branchLine);
471
            }
472
        }
473
474
        return $branches;
475 5
    }
476
477 5
    /**
478 5
     * Return the actually checked out branch
479
     *
480 5
     * @throws \RuntimeException
481
     * @throws \InvalidArgumentException
482 5
     * @throws \Symfony\Component\Process\Exception\RuntimeException
483 5
     * @return Objects\Branch
484
     */
485 5
    public function getMainBranch()
486
    {
487
        $filtered = array_filter(
488
            $this->getBranches(),
489
            function (Branch $branch) {
490
                return $branch->getCurrent();
491
            }
492
        );
493
        sort($filtered);
494
495
        return $filtered[0];
496
    }
497
498 9
    /**
499
     * Retrieve a Branch object by a branch name
500
     *
501 9
     * @param string $name The branch name
502 9
     *
503 9
     * @throws \RuntimeException
504
     * @throws \InvalidArgumentException
505 4
     * @throws \Symfony\Component\Process\Exception\RuntimeException
506
     * @return null|Branch
507 1
     */
508
    public function getBranch($name)
509
    {
510
        /** @var Branch $branch */
511
        foreach ($this->getBranches() as $branch) {
512
            if ($branch->getName() == $name) {
513
                return $branch;
514
            }
515
        }
516
517
        return null;
518
    }
519
520 1
    /**
521
     * Checkout all branches from the remote and make them local
522 1
     *
523 1
     * @param string $remote remote to fetch from
524 1
     *
525 1
     * @throws \RuntimeException
526 1
     * @throws \InvalidArgumentException
527 1
     * @throws \Symfony\Component\Process\Exception\RuntimeException
528 1
     * @return Repository
529 1
     */
530 1
    public function checkoutAllRemoteBranches($remote = 'origin')
531
    {
532 1
        $actualBranch = $this->getMainBranch();
533 1
        $actualBranches = $this->getBranches(true, false);
534 1
        $allBranches = $this->getBranches(true, true);
535 1
        $realBranches = array_filter(
536 1
            $allBranches,
537
            function ($branch) use ($actualBranches) {
538 1
                return !in_array($branch, $actualBranches)
539
                && preg_match('/^remotes(.+)$/', $branch)
540
                && !preg_match('/^(.+)(HEAD)(.*?)$/', $branch);
541
            }
542
        );
543
        foreach ($realBranches as $realBranch) {
544
            $this->checkout(str_replace(sprintf('remotes/%s/', $remote), '', $realBranch));
545
        }
546
        $this->checkout($actualBranch);
547
548
        return $this;
549
    }
550
551
    /**
552
     * Merge a Branch in the current checked out branch
553
     *
554 2
     * @param Objects\Branch $branch  The branch to merge in the current checked out branch
555
     * @param string         $message The message for the merge commit, if merge is 3-way
556
     * @param string         $mode    The merge mode: ff-only, no-ff or auto
557 2
     *
558 2
     * @throws \RuntimeException
559 2
     * @throws \Symfony\Component\Process\Exception\LogicException
560 2
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
561 2
     * @throws \Symfony\Component\Process\Exception\RuntimeException
562
     * @return Repository
563
     */
564
    public function merge(Branch $branch, $message = '', $mode = 'auto')
565 2
    {
566
        $valid_modes = array(
567 2
            'auto',    // deafult git behavior
568 1
            'ff-only', // force fast forward merge
569 1
            'no-ff',   // force 3-way merge
570 2
        );
571 1
        if (!in_array($mode, $valid_modes)) {
572 1
            throw new \Symfony\Component\Process\Exception\InvalidArgumentException("Invalid merge mode: $mode.");
573
        }
574
575 2
        $options = array();
576
        switch ($mode) {
577 2
            case 'ff-only':
578
                $options[] = MergeCommand::MERGE_OPTION_FF_ONLY;
579
                break;
580
            case 'no-ff':
581
                $options[] = MergeCommand::MERGE_OPTION_NO_FF;
582
                break;
583
        }
584
585
        $this->caller->execute(MergeCommand::getInstance($this)->merge($branch, $message, $options));
586
587
        return $this;
588
    }
589
590
    /**
591
     * Create a new tag
592 25
     * This function change the state of the repository on the filesystem
593
     *
594 25
     * @param string $name       The new tag name
595
     * @param null   $startPoint The reference to create the tag from
596 25
     * @param null   $message    the tag message
597
     *
598
     * @throws \RuntimeException
599
     * @throws \Symfony\Component\Process\Exception\RuntimeException
600
     * @return Repository
601
     */
602
    public function createTag($name, $startPoint = null, $message = null)
603
    {
604
        Tag::create($this, $name, $startPoint, $message);
605
606
        return $this;
607
    }
608
609 2
    /**
610
     * Delete a tag by it's name or by passing a Tag object
611 2
     * This function change the state of the repository on the filesystem
612 1
     *
613 1
     * @param string|Tag $tag The tag name or the Tag object
614 1
     *
615
     * @throws \RuntimeException
616
     * @throws \Symfony\Component\Process\Exception\RuntimeException
617 2
     * @return Repository
618
     */
619
    public function deleteTag($tag)
620
    {
621
        if ($tag instanceof Tag) {
622
            $tag->delete();
623
        } else {
624
            Tag::pick($this, $tag)->delete();
625
        }
626
627
        return $this;
628
    }
629
630
    /**
631
     * add a git submodule to the repository
632 1
     *
633
     * @param string $gitUrl git url of the submodule
634 1
     * @param string $path   path to register the submodule to
635
     *
636 1
     * @throws \RuntimeException
637
     * @throws \Symfony\Component\Process\Exception\LogicException
638
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
639
     * @throws \Symfony\Component\Process\Exception\RuntimeException
640
     * @return Repository
641
     */
642
    public function addSubmodule($gitUrl, $path = null)
643
    {
644
        $this->caller->execute(SubmoduleCommand::getInstance($this)->add($gitUrl, $path));
645
646
        return $this;
647
    }
648
649
    /**
650
     * initialize submodules
651
     *
652
     * @param  string $path init only submodules at the specified path
653
     *
654
     * @return Repository
655
     */
656
    public function initSubmodule($path = null)
657
    {
658
        $this->caller->execute(SubmoduleCommand::getInstance($this)->init($path));
659
        return $this;
660
    }
661
662
    /**
663
     * update submodules
664
     *
665
     * @param  bool   $recursive update recursively
666
     * @param  bool   $init      init before update
667
     * @param  bool   $force     force the checkout as part of update
668
     * @param  string $path      update only a specific submodule path
669
     *
670
     * @return Repository
671
     */
672
    public function updateSubmodule($recursive = false, $init = false, $force = false, $path = null)
673
    {
674
        $this->caller->execute(SubmoduleCommand::getInstance($this)->update($recursive, $init, $force, $path));
675
        return $this;
676
    }
677 2
678
    /**
679 2
     * Gets an array of Tag objects
680 2
     *
681 2
     * @throws \RuntimeException
682 2
     * @throws \Symfony\Component\Process\Exception\LogicException
683 2
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
684 2
     * @throws \Symfony\Component\Process\Exception\RuntimeException
685 2
     * @return array
686
     */
687 2
    public function getTags()
688
    {
689
        $tags = array();
690
        $this->caller->execute(TagCommand::getInstance($this)->listTags());
691
        foreach ($this->caller->getOutputLines() as $tagString) {
692
            if ($tagString != '') {
693
                $tags[] = new Tag($this, trim($tagString));
694
            }
695
        }
696
697
        return $tags;
698
    }
699 27
700
    /**
701 27
     * Return a tag object
702 27
     *
703 27
     * @param string $name The tag name
704 27
     *
705
     * @throws \RuntimeException
706 5
     * @throws \Symfony\Component\Process\Exception\RuntimeException
707
     * @return Tag|null
708 1
     */
709
    public function getTag($name)
710
    {
711
        $tagFinderOutput = $this->caller->execute(TagCommand::getInstance()->listTags())->getOutputLines(true);
712
        foreach ($tagFinderOutput as $line) {
713
            if ($line === $name) {
714
                return new Tag($this, $name);
715
            }
716
        }
717
718
        return null;
719 1
    }
720
721 1
    /**
722 1
     * Return the last created tag
723 1
     *
724 1
     * @throws \LogicException
725 1
     * @throws \RuntimeException
726
     * @throws \InvalidArgumentException
727
     * @return Tag|null
728 1
     */
729 1
    public function getLastTag()
730
    {
731 1
        $finder = Finder::create()
732 1
                  ->files()
733
                  ->in(sprintf('%s/.git/refs/tags', $this->path))
734 1
                  ->sortByChangedTime();
735
        if ($finder->count() == 0) {
736
            return null;
737
        }
738
        $files = iterator_to_array($finder->getIterator(), false);
739
        $files = array_reverse($files);
740
        /** @var $firstFile SplFileInfo */
741
        $firstFile = $files[0];
742
        $tagName = $firstFile->getFilename();
743
744
        return Tag::pick($this, $tagName);
745
    }
746
747 1
    /**
748
     * Try to get a branch or a tag by its name.
749 1
     *
750 1
     * @param string $name the reference name (a tag name or a branch name)
751
     *
752 1
     * @throws \RuntimeException
753 1
     * @throws \InvalidArgumentException
754 1
     * @throws \Symfony\Component\Process\Exception\RuntimeException
755 1
     * @return \GitElephant\Objects\Tag|\GitElephant\Objects\Branch|null
756
     */
757 1
    public function getBranchOrTag($name)
758
    {
759 1
        if (in_array($name, $this->getBranches(true))) {
760
            return new Branch($this, $name);
761
        }
762
        $tagFinderOutput = $this->caller->execute(TagCommand::getInstance($this)->listTags())->getOutputLines(true);
763
        foreach ($tagFinderOutput as $line) {
764
            if ($line === $name) {
765
                return new Tag($this, $name);
766
            }
767
        }
768
769
        return null;
770 11
    }
771
772 11
    /**
773
     * Return a Commit object
774 11
     *
775
     * @param string $ref The commit reference
776
     *
777
     * @throws \RuntimeException
778
     * @return Objects\Commit
779
     */
780
    public function getCommit($ref = 'HEAD')
781
    {
782
        $commit = Commit::pick($this, $ref);
783
784
        return $commit;
785
    }
786 1
787
    /**
788 1
     * count the commit to arrive to the given treeish
789
     *
790 1
     * @param string $start
791
     *
792
     * @throws \RuntimeException
793
     * @throws \Symfony\Component\Process\Exception\RuntimeException
794
     * @return int|void
795
     */
796
    public function countCommits($start = 'HEAD')
797
    {
798
        $commit = Commit::pick($this, $start);
799
800
        return $commit->count();
801
    }
802
803
    /**
804 20
     * Get a log for a ref
805
     *
806 20
     * @param string|TreeishInterface|array $ref         the treeish to check, as a string, as an object or as an array
807
     * @param string|Object                 $path        the physical path to the tree relative to the repository root
808
     * @param int|null                      $limit       limit to n entries
809
     * @param int|null                      $offset      skip n entries
810
     * @param boolean|false                 $firstParent skip commits brought in to branch by a merge
811
     *
812
     * @return \GitElephant\Objects\Log
813
     */
814
    public function getLog($ref = 'HEAD', $path = null, $limit = 10, $offset = null, $firstParent = false)
815
    {
816
        return new Log($this, $ref, $path, $limit, $offset, $firstParent);
0 ignored issues
show
Bug introduced by
It seems like $path defined by parameter $path on line 814 can also be of type object<GitElephant\Objects\Object> or string; however, GitElephant\Objects\Log::__construct() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
Bug introduced by
It seems like $offset defined by parameter $offset on line 814 can also be of type integer; however, GitElephant\Objects\Log::__construct() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
817
    }
818
819
    /**
820
     * Get a log for a range ref
821
     *
822
     * @param string        $refStart
823
     * @param string        $refEnd
824
     * @param string|Object $path        the physical path to the tree relative to the repository root
825
     * @param int|null      $limit       limit to n entries
826
     * @param int|null      $offset      skip n entries
827
     * @param boolean|false $firstParent skip commits brought in to branch by a merge
828
     *
829
     * @return \GitElephant\Objects\LogRange
830
     */
831
    public function getLogRange($refStart, $refEnd, $path = null, $limit = 10, $offset = null, $firstParent = false)
832
    {
833
        // Handle when clients provide bad start reference on branch creation
834
        if (preg_match('~^[0]+$~', $refStart)) {
835
            return new Log($this, $refEnd, $path, $limit, $offset, $firstParent);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return new \GitElephant\...$offset, $firstParent); (GitElephant\Objects\Log) is incompatible with the return type documented by GitElephant\Repository::getLogRange of type GitElephant\Objects\LogRange.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
Bug introduced by
It seems like $path defined by parameter $path on line 831 can also be of type object<GitElephant\Objects\Object> or string; however, GitElephant\Objects\Log::__construct() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
Bug introduced by
It seems like $offset defined by parameter $offset on line 831 can also be of type integer; however, GitElephant\Objects\Log::__construct() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
836
        }
837
838
        // Handle when clients provide bad end reference on branch deletion
839
        if (preg_match('~^[0]+$~', $refEnd)) {
840
            $refEnd = $refStart;
841
        }
842
843
        return new LogRange($this, $refStart, $refEnd, $path, $limit, $offset, $firstParent);
0 ignored issues
show
Bug introduced by
It seems like $path defined by parameter $path on line 831 can also be of type object<GitElephant\Objects\Object> or string; however, GitElephant\Objects\LogRange::__construct() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
Bug introduced by
It seems like $offset defined by parameter $offset on line 831 can also be of type integer; however, GitElephant\Objects\LogRange::__construct() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
844
    }
845
846
    /**
847
     * Get a log for an object
848
     *
849
     * @param \GitElephant\Objects\Object             $obj    The Object instance
850 3
     * @param null|string|\GitElephant\Objects\Branch $branch The branch to read from
851
     * @param int                                     $limit  Limit to n entries
852 3
     * @param int|null                                $offset Skip n entries
853
     *
854 3
     * @throws \RuntimeException
855
     * @throws \Symfony\Component\Process\Exception\LogicException
856
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
857
     * @throws \Symfony\Component\Process\Exception\RuntimeException
858
     * @return \GitElephant\Objects\Log
859
     */
860
    public function getObjectLog(Object $obj, $branch = null, $limit = 1, $offset = null)
861
    {
862
        $command = LogCommand::getInstance($this)->showObjectLog($obj, $branch, $limit, $offset);
863
864
        return Log::createFromOutputLines($this, $this->caller->execute($command)->getOutputLines());
865
    }
866
867
    /**
868
     * Checkout a branch
869
     * This function change the state of the repository on the filesystem
870 24
     *
871
     * @param string|TreeishInterface $ref    the reference to checkout
872 24
     * @param bool                    $create like -b on the command line
873
     *
874
     * @throws \RuntimeException
875 24
     * @throws \Symfony\Component\Process\Exception\LogicException
876
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
877 24
     * @throws \Symfony\Component\Process\Exception\RuntimeException
878
     * @return Repository
879
     */
880
    public function checkout($ref, $create = false)
881
    {
882
        if ($create && is_null($this->getBranch($ref))) {
0 ignored issues
show
Bug introduced by
It seems like $ref defined by parameter $ref on line 880 can also be of type object<GitElephant\Objects\TreeishInterface>; however, GitElephant\Repository::getBranch() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
883
            $this->createBranch($ref);
0 ignored issues
show
Bug introduced by
It seems like $ref defined by parameter $ref on line 880 can also be of type object<GitElephant\Objects\TreeishInterface>; however, GitElephant\Repository::createBranch() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
884
        }
885
        $this->caller->execute(MainCommand::getInstance($this)->checkout($ref));
0 ignored issues
show
Bug introduced by
It seems like $ref defined by parameter $ref on line 880 can also be of type object<GitElephant\Objects\TreeishInterface>; however, GitElephant\Command\MainCommand::checkout() does only seem to accept string|object<GitElephant\Objects\Branch>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
886
887
        return $this;
888
    }
889
890
    /**
891
     * Retrieve an instance of Tree
892
     * Tree Object is Countable, Iterable and has ArrayAccess for easy manipulation
893 15
     *
894
     * @param string|TreeishInterface $ref  the treeish to check
895 15
     * @param string|Object           $path Object or null for root
896 9
     *
897 9
     * @throws \RuntimeException
898 9
     * @throws \Symfony\Component\Process\Exception\LogicException
899 9
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
900 9
     * @throws \Symfony\Component\Process\Exception\RuntimeException
901
     * @return Objects\Tree
902 15
     */
903
    public function getTree($ref = 'HEAD', $path = null)
904
    {
905
        if (is_string($path) && '' !== $path) {
906
            $outputLines = $this->getCaller()->execute(
907
                LsTreeCommand::getInstance($this)->tree($ref, $path)
0 ignored issues
show
Bug introduced by
It seems like $ref defined by parameter $ref on line 903 can also be of type object<GitElephant\Objects\TreeishInterface>; however, GitElephant\Command\LsTreeCommand::tree() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
908
            )->getOutputLines(true);
909
            $path = TreeObject::createFromOutputLine($this, $outputLines[0]);
910
        }
911
912
        return new Tree($this, $ref, $path);
0 ignored issues
show
Bug introduced by
It seems like $ref defined by parameter $ref on line 903 can also be of type object<GitElephant\Objects\TreeishInterface>; however, GitElephant\Objects\Tree::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
Bug introduced by
It seems like $path defined by parameter $path on line 903 can also be of type string; however, GitElephant\Objects\Tree::__construct() does only seem to accept object|null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
913
    }
914
915
    /**
916 2
     * Get a Diff object for a commit with its parent, by default the diff is between the current head and its parent
917
     *
918 2
     * @param \GitElephant\Objects\Commit|string      $commit1 A TreeishInterface instance
919
     * @param \GitElephant\Objects\Commit|string|null $commit2 A TreeishInterface instance
920
     * @param null|string|Object                      $path    The path to get the diff for or a Object instance
921
     *
922
     * @throws \RuntimeException
923
     * @throws \InvalidArgumentException
924
     * @return Objects\Diff\Diff
925
     */
926
    public function getDiff($commit1 = null, $commit2 = null, $path = null)
927
    {
928
        return Diff::create($this, $commit1, $commit2, $path);
0 ignored issues
show
Bug introduced by
It seems like $path defined by parameter $path on line 926 can also be of type object<GitElephant\Objects\Object>; however, GitElephant\Objects\Diff\Diff::create() does only seem to accept null|string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
929
    }
930
931
    /**
932
     * Clone a repository
933 2
     *
934
     * @param string $url the repository url (i.e. git://github.com/matteosister/GitElephant.git)
935 2
     * @param null   $to  where to clone the repo
936
     *
937 2
     * @throws \RuntimeException
938
     * @throws \Symfony\Component\Process\Exception\LogicException
939
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
940
     * @throws \Symfony\Component\Process\Exception\RuntimeException
941
     * @return Repository
942
     */
943
    public function cloneFrom($url, $to = null)
944
    {
945
        $this->caller->execute(CloneCommand::getInstance($this)->cloneUrl($url, $to));
946
947
        return $this;
948
    }
949
950 7
    /**
951
     * @param string $name remote name
952 7
     * @param string $url  remote url
953
     *
954 7
     * @throws \RuntimeException
955
     * @throws \Symfony\Component\Process\Exception\LogicException
956
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
957
     * @throws \Symfony\Component\Process\Exception\RuntimeException
958
     * @return Repository
959
     */
960
    public function addRemote($name, $url)
961
    {
962
        $this->caller->execute(RemoteCommand::getInstance($this)->add($name, $url));
963 1
964
        return $this;
965 1
    }
966
967
    /**
968
     * @param string $name         remote name
969
     * @param bool   $queryRemotes Fetch new information from remotes
970
     *
971
     * @return \GitElephant\Objects\Remote
972
     */
973
    public function getRemote($name, $queryRemotes = true)
974
    {
975
        return Remote::pick($this, $name, $queryRemotes);
976
    }
977
978
    /**
979 1
     * gets a list of remote objects
980
     *
981 1
     * @param bool $queryRemotes Fetch new information from remotes
982 1
     *
983 1
     * @throws \RuntimeException
984 1
     * @throws \Symfony\Component\Process\Exception\LogicException
985 1
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
986 1
     * @throws \Symfony\Component\Process\Exception\RuntimeException
987
     * @return array
988 1
     */
989
    public function getRemotes($queryRemotes = true)
990
    {
991
        $remoteNames = $this->caller->execute(RemoteCommand::getInstance($this)->show(null, $queryRemotes))
992
          ->getOutputLines(true);
993
        $remotes = array();
994
        foreach ($remoteNames as $remoteName) {
995
            $remotes[] = $this->getRemote($remoteName, $queryRemotes);
996
        }
997
998
        return $remotes;
999
    }
1000
1001
    /**
1002
     * Download objects and refs from another repository
1003 1
     *
1004
     * @param string $from
1005 1
     * @param string $ref
1006 1
     * @param bool   $tags
1007 1
     *
1008 1
     * @throws \RuntimeException
1009 1
     * @throws \Symfony\Component\Process\Exception\LogicException
1010 1
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
1011
     * @throws \Symfony\Component\Process\Exception\RuntimeException
1012
     */
1013
    public function fetch($from = null, $ref = null, $tags = false)
1014
    {
1015
        $options = array();
1016
        if ($tags === true) {
1017
            $options = array('--tags');
1018
        }
1019
        $this->caller->execute(FetchCommand::getInstance($this)->fetch($from, $ref, $options));
1020
    }
1021
1022
    /**
1023 2
     * Fetch from and merge with another repository or a local branch
1024
     *
1025 2
     * @param string $from
1026 2
     * @param string $ref
1027
     * @param bool   $rebase
1028
     * @throws \RuntimeException
1029
     * @throws \Symfony\Component\Process\Exception\LogicException
1030
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
1031
     * @throws \Symfony\Component\Process\Exception\RuntimeException
1032
     */
1033
    public function pull($from = null, $ref = null, $rebase = true)
1034
    {
1035
        $this->caller->execute(PullCommand::getInstance($this)->pull($from, $ref, $rebase));
1036
    }
1037
1038 1
    /**
1039
     * Fetch from and merge with another repository or a local branch
1040 1
     *
1041 1
     * @param string $to
1042
     * @param string $ref
1043
     * @throws \RuntimeException
1044
     * @throws \Symfony\Component\Process\Exception\LogicException
1045
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
1046
     * @throws \Symfony\Component\Process\Exception\RuntimeException
1047
     */
1048 2
    public function push($to = null, $ref = null)
1049
    {
1050 2
        $this->caller->execute(PushCommand::getInstance($this)->push($to, $ref));
1051 2
    }
1052 2
1053
    /**
1054 2
     * get the humanish name of the repository
1055
     *
1056
     * @return string
1057
     */
1058
    public function getHumanishName()
1059
    {
1060
        $name = substr($this->getPath(), strrpos($this->getPath(), '/') + 1);
1061
        $name = str_replace('.git', '.', $name);
1062
        $name = str_replace('.bundle', '.', $name);
1063
1064
        return $name;
1065
    }
1066
1067
    /**
1068
     * output a node content as an array of lines
1069 1
     *
1070
     * @param \GitElephant\Objects\Object                  $obj     The Object of type BLOB
1071 1
     * @param \GitElephant\Objects\TreeishInterface|string $treeish A treeish object
1072
     *
1073 1
     * @throws \RuntimeException
1074
     * @throws \Symfony\Component\Process\Exception\LogicException
1075
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
1076
     * @throws \Symfony\Component\Process\Exception\RuntimeException
1077
     * @return array
1078
     */
1079
    public function outputContent(Object $obj, $treeish)
1080
    {
1081
        $command = CatFileCommand::getInstance($this)->content($obj, $treeish);
1082
1083
        return $this->caller->execute($command)->getOutputLines();
1084
    }
1085
1086
    /**
1087
     * output a node raw content
1088
     *
1089
     * @param \GitElephant\Objects\Object                  $obj     The Object of type BLOB
1090
     * @param \GitElephant\Objects\TreeishInterface|string $treeish A treeish object
1091
     *
1092
     * @throws \RuntimeException
1093
     * @throws \Symfony\Component\Process\Exception\LogicException
1094
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
1095
     * @throws \Symfony\Component\Process\Exception\RuntimeException
1096
     * @return string
1097
     */
1098
    public function outputRawContent(Object $obj, $treeish)
1099
    {
1100 59
        $command = CatFileCommand::getInstance($this)->content($obj, $treeish);
1101
1102 59
        return $this->caller->execute($command)->getRawOutput();
1103
    }
1104
1105
    /**
1106
     * Get the path
1107
     *
1108
     * @return string
1109
     */
1110 1
    public function getPath()
1111
    {
1112 1
        return $this->path;
1113
    }
1114
1115
    /**
1116
     * Get the repository name
1117
     *
1118
     * @return string
1119
     */
1120 1
    public function getName()
1121
    {
1122 1
        return $this->name;
1123 1
    }
1124
1125
    /**
1126
     * Set the repository name
1127
     *
1128
     * @param string $name the repository name
1129
     */
1130
    public function setName($name)
1131
    {
1132
        $this->name = $name;
1133
    }
1134
1135
    /**
1136
     * Caller setter
1137
     *
1138
     * @param \GitElephant\Command\Caller\Caller $caller the caller variable
1139
     */
1140 84
    public function setCaller($caller)
1141
    {
1142 84
        $this->caller = $caller;
1143
    }
1144
1145
    /**
1146
     * Caller getter
1147
     *
1148
     * @return \GitElephant\Command\Caller\Caller
1149
     */
1150 90
    public function getCaller()
1151
    {
1152 90
        return $this->caller;
1153
    }
1154
1155
    /**
1156
     * get global config list
1157
     *
1158
     * @return array Global config list
1159
     */
1160
    public function getGlobalConfigs()
1161 1
    {
1162
        return $this->globalConfigs;
1163 1
    }
1164 1
1165
    /**
1166
     * add a key/value pair to the global config list
1167
     *
1168
     * @param string $name  The config name
1169
     * @param string $value The config value
1170
     */
1171 1
    public function addGlobalConfig($name, $value)
1172
    {
1173 1
        $this->globalConfigs[$name] = $value;
1174 1
    }
1175 1
1176 1
    /**
1177
     * remove an element form the global config list, identified by key
1178
     *
1179
     * @param  string $name The config name
1180
     */
1181
    public function removeGlobalConfig($name)
1182
    {
1183 90
        if (isset($this->globalConfigs[$name])) {
1184
            unset($this->globalConfigs[$name]);
1185 90
        }
1186
    }
1187
1188
    /**
1189
     * get global options list
1190
     *
1191
     * @return array Global options list
1192
     */
1193
    public function getGlobalOptions()
1194 1
    {
1195
        return $this->globalOptions;
1196 1
    }
1197 1
1198
    /**
1199
     * add a key/value pair to the global option list
1200
     *
1201
     * @param string $name  The option name
1202
     * @param string $value The option value
1203
     */
1204 1
    public function addGlobalOption($name, $value)
1205
    {
1206 1
        $this->globalOptions[$name] = $value;
1207 1
    }
1208 1
1209 1
    /**
1210
     * remove an element form the global option list, identified by key
1211
     *
1212
     * @param  string $name The option name
1213
     */
1214
    public function removeGlobalOption($name)
1215
    {
1216 90
        if (isset($this->globalOptions[$name])) {
1217
            unset($this->globalOptions[$name]);
1218 90
        }
1219
    }
1220
1221
    /**
1222
     * get global command arguments list
1223
     *
1224
     * @return array Global command arguments list
1225
     */
1226 1
    public function getGlobalCommandArguments()
1227
    {
1228 1
        return $this->globalCommandArguments;
1229 1
    }
1230 1
1231 1
    /**
1232
     * add a value to the global command argument list
1233
     *
1234
     * @param string $value The command argument
1235
     */
1236
    public function addGlobalCommandArgument($value)
1237
    {
1238
        if (!in_array($value, $this->globalCommandArguments, true)) {
1239 1
            $this->globalCommandArguments[] = $value;
1240
        }
1241 1
    }
1242 1
1243 1
    /**
1244 1
     * remove an element form the global command argument list, identified by 
1245 1
     * value
1246
     *
1247
     * @param  string $value The command argument
1248
     */
1249
    public function removeGlobalCommandArgument($value)
1250
    {
1251
        if (in_array($value, $this->globalCommandArguments, true)) {
1252
            $index = array_search($value, $this->globalCommandArguments);
1253
            unset($this->globalCommandArguments[$index]);
1254
        }
1255
    }
1256
}
1257