#include "ls-tree.h" #include #include #include #include #include #include "zstr.hpp" int lsTree(const int argc, const char** argv) { bool nameOnly = false; if (argc == 4) { const std::string flag = argv[2]; if (flag != "--name-only") { std::cerr << flag << "is an invalid flag, please use \"--name-only\"\n"; return 1; } nameOnly = true; } const std::string input = nameOnly ? argv[3] : argv[2]; const std::string dir = input.substr(0, 2); const std::string file = input.substr(2); zstr::ifstream inputFile("./.git/objects/" + dir + "/" + file, std::ofstream::binary); if (!inputFile.is_open()) { std::cerr << "Could not open file\n"; return 1; } const std::string output{std::istreambuf_iterator(inputFile), std::istreambuf_iterator()}; //start right after tree \0 size_t startChar = output.find('\0') + 1; size_t nextNullChar = output.find('\0', startChar); while (nextNullChar != std::string::npos) { const std::string_view modeAndName = std::string_view(output).substr(startChar, nextNullChar - startChar); const std::string_view mode = modeAndName.substr(0, modeAndName.find(' ')); const std::string_view name = modeAndName.substr(modeAndName.find(' ') + 1); const std::string_view hash = std::string_view(output).substr(nextNullChar + 1, 20); if (!nameOnly) { if (mode == "100644" or mode == "100755") { std::cout << mode << ' '; std::cout << "blob "; } else {//assume it's a tree obj std::cout << "0" << mode << ' '; std::cout << "tree "; } for (const auto& value : hash) std::printf("%02x", static_cast(value)); // simpler solution std::cout << " "; } std::cout << name << "\n"; startChar = nextNullChar + 21; nextNullChar = output.find('\0', startChar); } inputFile.close(); return 0; }