Skip to content

Commit 2d39fba

Browse files
Feat/recognise shorthands (#55)
* Add tests and update the GitObject::find function * Adopt shorthands for relevant commands * fix tests
1 parent 8261cea commit 2d39fba

22 files changed

+317
-46
lines changed

.gitignore

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,16 @@
3131
*.out
3232
*.app
3333
app/gyt
34-
tests/tests
3534
build/**/*
3635

36+
# Tests
37+
tests/tests
38+
tests/_deps
39+
tests/.ninja*
40+
tests/app/gyt
41+
tests/Testing
42+
tests/build.ninja
43+
3744
# CMake files
3845
*.cmake
3946
**/CMakeFiles/

doc/commands/branches.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Branches
2+
3+
A branch:
4+
- is a ref under ref/heads
5+
6+
# commands that creates branches
7+
8+
`git branch -c`
9+
`git checkout -b`
10+
`git switch -c`

src/commands/cat-file.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ void catfile(std::vector<std::string> &args) {
2626
try {
2727
std::optional<GitRepository> repo = GitRepository::find();
2828
if (repo) {
29-
// TODO use GitObject::find once it's fixed
30-
GitObject *obj = GitObject::read(*repo, hash);
29+
GitObject *obj = GitObject::read(*repo, GitObject::find(*repo, hash));
3130
std::cout << obj->serialise(*repo);
3231
}
3332
} catch (std::runtime_error &err) {

src/commands/checkout.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ void checkout(std::vector<std::string> &args) {
2424
try {
2525
std::optional<GitRepository> repo = GitRepository::find();
2626
if (repo) {
27-
GitCommit *commit =
28-
dynamic_cast<GitCommit *>(GitObject::read(*repo, hash));
27+
GitCommit *commit = dynamic_cast<GitCommit *>(
28+
GitObject::read(*repo, GitObject::find(*repo, hash)));
2929
if (!commit) {
3030
throw std::runtime_error("Invalid commit object: " + hash);
3131
}

src/commands/log.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ void log(std::vector<std::string> &args) {
2121
try {
2222
std::optional<GitRepository> repo = GitRepository::find();
2323
if (repo) {
24-
std::string commit = commitArg.getValue();
24+
std::string commit = GitObject::find(*repo, commitArg.getValue());
2525
GitCommit *commitObj;
2626

2727
do {

src/commands/ls-tree.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "commands/ls-tree.h"
22
#include <iostream>
3+
#include <string>
34

45
#include "object.h"
56
#include "repository.h"

src/object.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "object.h"
22
#include "blob.h"
3+
#include "boost/algorithm/string/case_conv.hpp"
34
#include "commit.h"
45
#include "tree.h"
56
#include "util.h"
@@ -90,18 +91,26 @@ std::string GitObject::write(GitRepository &repo, std::string &type,
9091
}
9192
}
9293

93-
// TODO support hashes here
94+
// XXX: food for thought: how does git handle the situation where
95+
// the branch name is the same as a tag?
9496
std::string GitObject::find(GitRepository &repo, const std::string &name,
9597
bool follow) {
9698
fs::path ref_path;
97-
if (name == "HEAD") {
99+
std::string ref_name = boost::algorithm::to_lower_copy(name);
100+
if (ref_name == "head") {
98101
ref_path = repo.repo_path("HEAD");
102+
} else if (fs::exists(repo.repo_path("refs/heads/" + ref_name))) {
103+
ref_path = repo.repo_path("refs/heads/" + ref_name);
104+
} else if (fs::exists(repo.repo_path("refs/tags/" + ref_name))) {
105+
ref_path = repo.repo_path("refs/tags/" + ref_name);
106+
} else if (fs::exists(repo.repo_path("refs/remotes/" + ref_name))) {
107+
ref_path = repo.repo_path("refs/remotes/" + ref_name);
108+
} else if (fs::exists(repo.repo_path(get_commit_path(ref_name)))) {
109+
return ref_name;
99110
} else {
100-
ref_path = repo.repo_path("refs/heads/" + name);
111+
throw std::runtime_error(name + ": not a valid reference");
101112
}
102-
std::string file_data = read_file(ref_path, true);
103-
std::string commit_hash = file_data.substr(5);
104-
return read_file(repo.repo_path(commit_hash), true);
113+
return resolve_ref(ref_path, repo);
105114
}
106115

107116
std::string GitObject::get_type() const { return this->format; }

test.sh

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,18 @@ fi
2020
echo "Selected build type: $BUILD_TYPE"
2121
echo "Building the project... This will take a while to install dependencies for the first time."
2222

23-
mv ../tests/gitrepo/.notgit ../tests/gitrepo/.git
23+
rm -rf ../tests/gitrepo/.git
24+
cp -R ../tests/gitrepo/.notgit ../tests/gitrepo/.git
2425

2526
#Run CMake with the selected build type
26-
cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -G Ninja
27+
cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DBUILD_TESTS=ON -G Ninja
2728

2829
#Build the project
2930
ninja
3031

3132
# test
3233
ctest --output-on-failure
3334

34-
mv ../tests/gitrepo/.git ../tests/gitrepo/.notgit
35-
3635
#symlink - so I can run it like gyt[arguments....]
3736
sudo rm /usr/local/bin/gyt
3837
sudo ln -s "$(pwd)/app/gyt" /usr/local/bin/gyt

tests/CMakeLists.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
add_executable(tests tests.cpp repository_t.cpp tag_t.cpp)
1+
add_executable(tests tests.cpp repository_t.cpp tag_t.cpp object_t.cpp utils/gitreposetup.cpp)
22
target_include_directories(tests PUBLIC ../ext)
33

44
target_link_libraries(tests PUBLIC boost_libraries repository commands)
55
file(COPY ${CMAKE_SOURCE_DIR}/tests/gitrepo
6-
DESTINATION ${CMAKE_BINARY_DIR}/tests
7-
FILES_MATCHING PATTERN ".*" PATTERN "*" EXCLUDE)
6+
DESTINATION ${CMAKE_BINARY_DIR}/tests)
87

98
# allow user to run tests with `make test` or `ctest`
109
include(../cmake/Catch.cmake)

0 commit comments

Comments
 (0)