Skip to content

Commit b4326ff

Browse files
committed
Add show-ref subcommand
1 parent 22db9ed commit b4326ff

7 files changed

Lines changed: 103 additions & 1 deletion

File tree

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ set(GIT2CPP_SRC
7878
${GIT2CPP_SOURCE_DIR}/subcommand/revparse_subcommand.hpp
7979
${GIT2CPP_SOURCE_DIR}/subcommand/rm_subcommand.cpp
8080
${GIT2CPP_SOURCE_DIR}/subcommand/rm_subcommand.hpp
81+
${GIT2CPP_SOURCE_DIR}/subcommand/showref_subcommand.cpp
82+
${GIT2CPP_SOURCE_DIR}/subcommand/showref_subcommand.hpp
8183
${GIT2CPP_SOURCE_DIR}/subcommand/stash_subcommand.cpp
8284
${GIT2CPP_SOURCE_DIR}/subcommand/stash_subcommand.hpp
8385
${GIT2CPP_SOURCE_DIR}/subcommand/status_subcommand.cpp

src/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "subcommand/revlist_subcommand.hpp"
2424
#include "subcommand/revparse_subcommand.hpp"
2525
#include "subcommand/rm_subcommand.hpp"
26+
#include "subcommand/showref_subcommand.hpp"
2627
#include "subcommand/stash_subcommand.hpp"
2728
#include "subcommand/status_subcommand.hpp"
2829
#include "subcommand/tag_subcommand.hpp"
@@ -63,6 +64,7 @@ int main(int argc, char** argv)
6364
rm_subcommand rm(lg2_obj, app);
6465
stash_subcommand stash(lg2_obj, app);
6566
tag_subcommand tag(lg2_obj, app);
67+
showref_subcommand showref(lg2_obj, app);
6668

6769
app.require_subcommand(/* min */ 0, /* max */ 1);
6870

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include "showref_subcommand.hpp"
2+
3+
#include <git2.h>
4+
5+
#include "../wrapper/repository_wrapper.hpp"
6+
7+
showref_subcommand::showref_subcommand(const libgit2_object&, CLI::App& app)
8+
{
9+
auto* sub = app.add_subcommand("show-ref", "List references in a local repository");
10+
11+
sub->callback(
12+
[this]()
13+
{
14+
this->run();
15+
}
16+
);
17+
};
18+
19+
void showref_subcommand::run()
20+
{
21+
auto directory = get_current_git_path();
22+
auto repo = repository_wrapper::open(directory);
23+
24+
auto repo_refs = repo.refs_list();
25+
26+
for (auto r:repo_refs)
27+
{
28+
git_oid oid = repo.ref_name_to_id(r);
29+
std::cout << oid_to_hex(oid) << " " << r << std::endl;
30+
}
31+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
#include <CLI/CLI.hpp>
4+
5+
#include "../utils/common.hpp"
6+
7+
class showref_subcommand
8+
{
9+
public:
10+
11+
explicit showref_subcommand(const libgit2_object&, CLI::App& app);
12+
void run();
13+
14+
private:
15+
16+
17+
};

src/wrapper/repository_wrapper.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <git2.h>
88

9+
#include "../utils/common.hpp"
910
#include "../utils/git_exception.hpp"
1011
#include "../wrapper/annotated_commit_wrapper.hpp"
1112
#include "../wrapper/branch_wrapper.hpp"

test/test_fetch.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import pytest
21
import subprocess
32

3+
import pytest
4+
45

56
@pytest.mark.parametrize("protocol", ["http", "https"])
67
def test_fetch_private_repo(git2cpp_path, tmp_path, run_in_tmp_path, private_test_repo, protocol):

test/test_showref.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import re
2+
import subprocess
3+
4+
5+
def test_showref_list(repo_init_with_commit, git2cpp_path, tmp_path):
6+
"""`show-ref` lists the repository references (heads present after init+commit)."""
7+
cmd = [git2cpp_path, "show-ref"]
8+
p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
9+
assert p.returncode == 0
10+
# repo_init_with_commit in conftest creates the branch "main"
11+
assert "refs/heads/main" in p.stdout
12+
13+
14+
def test_showref_includes_tag(repo_init_with_commit, git2cpp_path, tmp_path):
15+
"""A created tag appears in show-ref output as refs/tags/<name>."""
16+
# create a lightweight tag using the CLI under test
17+
subprocess.run([git2cpp_path, "tag", "v1.0"], cwd=tmp_path, check=True)
18+
19+
p = subprocess.run([git2cpp_path, "show-ref"], capture_output=True, cwd=tmp_path, text=True)
20+
assert p.returncode == 0
21+
assert "refs/tags/v1.0" in p.stdout
22+
23+
24+
def test_showref_line_format(repo_init_with_commit, git2cpp_path, tmp_path):
25+
"""Each line of show-ref is: <40-hex-oid> <refname>."""
26+
p = subprocess.run([git2cpp_path, "show-ref"], capture_output=True, cwd=tmp_path, text=True)
27+
assert p.returncode == 0
28+
print(p.stdout)
29+
30+
hex_re = re.compile(r"^[0-9a-f]{40}$")
31+
for line in p.stdout.splitlines():
32+
line = line.strip()
33+
if not line:
34+
continue
35+
parts = line.split()
36+
# Expect at least two tokens: oid and refname
37+
assert len(parts) >= 2
38+
oid, refname = parts[0], parts[1]
39+
assert hex_re.match(oid), f"OID not a 40-char hex: {oid!r}"
40+
assert refname.startswith("refs/"), f"Refname does not start with refs/: {refname!r}"
41+
42+
43+
def test_showref_nogit(git2cpp_path, tmp_path):
44+
"""Running show-ref outside a repository returns an error and non-zero exit."""
45+
cmd = [git2cpp_path, "show-ref"]
46+
p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
47+
assert p.returncode != 0
48+
assert "error: could not find repository at" in p.stderr

0 commit comments

Comments
 (0)