diffLinesOfContext; } public function setDiffLinesOfContext($lines) { $this->diffLinesOfContext = $lines; return $this; } public static function newAPIFromWorkingCopyIdentity( ArcanistWorkingCopyIdentity $working_copy) { $root = $working_copy->getProjectRoot(); if (!$root) { throw new ArcanistUsageException( "There is no readable '.arcconfig' file in the working directory or ". "any parent directory. Create an '.arcconfig' file to configure arc."); } if (Filesystem::pathExists($root.'/.svn')) { return newv('ArcanistSubversionAPI', array($root)); } if (Filesystem::pathExists($root.'/.hg')) { // TODO: Stabilize and remove. file_put_contents( 'php://stderr', phutil_console_format( "**WARNING:** Mercurial support is largely imaginary right now.\n")); return newv('ArcanistMercurialAPI', array($root)); } $git_root = self::discoverGitBaseDirectory($root); if ($git_root) { if (!Filesystem::pathsAreEquivalent($root, $git_root)) { throw new ArcanistUsageException( "'.arcconfig' file is located at '{$root}', but working copy root ". "is '{$git_root}'. Move '.arcconfig' file to the working copy root."); } return newv('ArcanistGitAPI', array($root)); } throw new ArcanistUsageException( "The current working directory is not part of a working copy for a ". "supported version control system (svn, git or mercurial)."); } public function __construct($path) { $this->path = $path; } public function getPath($to_file = null) { if ($to_file !== null) { return $this->path.'/'.ltrim($to_file, '/'); } else { return $this->path.'/'; } } public function getUntrackedChanges() { return $this->getWorkingCopyFilesWithMask(self::FLAG_UNTRACKED); } public function getUnstagedChanges() { return $this->getWorkingCopyFilesWithMask(self::FLAG_UNSTAGED); } public function getUncommittedChanges() { return $this->getWorkingCopyFilesWithMask(self::FLAG_UNCOMMITTED); } public function getMergeConflicts() { return $this->getWorkingCopyFilesWithMask(self::FLAG_CONFLICT); } public function getIncompleteChanges() { return $this->getWorkingCopyFilesWithMask(self::FLAG_INCOMPLETE); } private function getWorkingCopyFilesWithMask($mask) { $match = array(); foreach ($this->getWorkingCopyStatus() as $file => $flags) { if ($flags & $mask) { $match[] = $file; } } return $match; } private static function discoverGitBaseDirectory($root) { try { list($stdout) = execx( '(cd %s; git rev-parse --show-cdup)', $root); return Filesystem::resolvePath(rtrim($stdout, "\n"), $root); } catch (CommandException $ex) { if (preg_match('/^fatal: Not a git repository/', $ex->getStdErr())) { return null; } throw $ex; } } abstract public function getBlame($path); abstract public function getWorkingCopyStatus(); abstract public function getRawDiffText($path); abstract public function getOriginalFileData($path); abstract public function getCurrentFileData($path); abstract public function getLocalCommitInformation(); }