Serenity Operating System
at master 133 lines 3.6 kB view raw
1/* 2 * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include "GitRepo.h" 8#include <LibCore/Command.h> 9 10namespace HackStudio { 11 12GitRepo::CreateResult GitRepo::try_to_create(DeprecatedString const& repository_root) 13{ 14 if (!git_is_installed()) { 15 return { CreateResult::Type::GitProgramNotFound, nullptr }; 16 } 17 if (!git_repo_exists(repository_root)) { 18 return { CreateResult::Type::NoGitRepo, nullptr }; 19 } 20 21 return { CreateResult::Type::Success, adopt_ref(*new GitRepo(repository_root)) }; 22} 23 24RefPtr<GitRepo> GitRepo::initialize_repository(DeprecatedString const& repository_root) 25{ 26 auto res = command_wrapper({ "init" }, repository_root); 27 if (res.is_null()) 28 return {}; 29 30 VERIFY(git_repo_exists(repository_root)); 31 return adopt_ref(*new GitRepo(repository_root)); 32} 33 34Vector<DeprecatedString> GitRepo::unstaged_files() const 35{ 36 auto modified = modified_files(); 37 auto untracked = untracked_files(); 38 modified.extend(move(untracked)); 39 return modified; 40} 41// 42Vector<DeprecatedString> GitRepo::staged_files() const 43{ 44 auto raw_result = command({ "diff", "--cached", "--name-only" }); 45 if (raw_result.is_null()) 46 return {}; 47 return parse_files_list(raw_result); 48} 49 50Vector<DeprecatedString> GitRepo::modified_files() const 51{ 52 auto raw_result = command({ "ls-files", "--modified", "--exclude-standard" }); 53 if (raw_result.is_null()) 54 return {}; 55 return parse_files_list(raw_result); 56} 57 58Vector<DeprecatedString> GitRepo::untracked_files() const 59{ 60 auto raw_result = command({ "ls-files", "--others", "--exclude-standard" }); 61 if (raw_result.is_null()) 62 return {}; 63 return parse_files_list(raw_result); 64} 65 66Vector<DeprecatedString> GitRepo::parse_files_list(DeprecatedString const& raw_result) 67{ 68 auto lines = raw_result.split('\n'); 69 Vector<DeprecatedString> files; 70 for (auto const& line : lines) { 71 files.empend(line); 72 } 73 return files; 74} 75 76DeprecatedString GitRepo::command(Vector<DeprecatedString> const& command_parts) const 77{ 78 return command_wrapper(command_parts, m_repository_root); 79} 80 81DeprecatedString GitRepo::command_wrapper(Vector<DeprecatedString> const& command_parts, DeprecatedString const& chdir) 82{ 83 auto result = Core::command("git", command_parts, LexicalPath(chdir)); 84 if (result.is_error() || result.value().exit_code != 0) 85 return {}; 86 return result.value().output; 87} 88 89bool GitRepo::git_is_installed() 90{ 91 return !command_wrapper({ "--help" }, "/").is_null(); 92} 93 94bool GitRepo::git_repo_exists(DeprecatedString const& repo_root) 95{ 96 return !command_wrapper({ "status" }, repo_root).is_null(); 97} 98 99bool GitRepo::stage(DeprecatedString const& file) 100{ 101 return !command({ "add", file }).is_null(); 102} 103 104bool GitRepo::unstage(DeprecatedString const& file) 105{ 106 return !command({ "reset", "HEAD", "--", file }).is_null(); 107} 108 109bool GitRepo::commit(DeprecatedString const& message) 110{ 111 return !command({ "commit", "-m", message }).is_null(); 112} 113 114Optional<DeprecatedString> GitRepo::original_file_content(DeprecatedString const& file) const 115{ 116 return command({ "show", DeprecatedString::formatted("HEAD:{}", file) }); 117} 118 119Optional<DeprecatedString> GitRepo::unstaged_diff(DeprecatedString const& file) const 120{ 121 return command({ "diff", file.characters() }); 122} 123 124bool GitRepo::is_tracked(DeprecatedString const& file) const 125{ 126 auto res = command({ "ls-files", file }); 127 if (res.is_null()) 128 return false; 129 130 return !res.is_empty(); 131} 132 133}