Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Small fix in log and status
  • Loading branch information
SandrineP committed Jan 6, 2026
commit 88708e64ce5297859f460dbea064bd90f29cfd74
6 changes: 6 additions & 0 deletions src/subcommand/log_subcommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ void log_subcommand::run()
auto repo = repository_wrapper::open(directory);
// auto branch_name = repo.head().short_name();

if (repo.is_head_unborn())
{
std::cout << "fatal: your current branch 'main' does not have any commits yet" << std::endl;
return;
}

revwalk_wrapper walker = repo.new_walker();
walker.push_head();

Expand Down
10 changes: 9 additions & 1 deletion src/subcommand/status_subcommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ void status_subcommand::run()
{
std::cout << "On branch " << branch_name << "\n" << std::endl;

if (repo.is_head_unborn())
{
std::cout << "No commits yet\n" << std::endl;
}

if (sl.has_unmerged_header())
{
std::cout << "You have unmerged paths.\n (fix conflicts and run \"git commit\")\n (use \"git merge --abort\" to abort the merge)\n" << std::endl;
Expand Down Expand Up @@ -274,6 +279,9 @@ void status_subcommand::run()
// TODO: check if this message should be displayed even if there are untracked files
if (!(sl.has_tobecommited_header() | sl.has_notstagged_header() | sl.has_unmerged_header() | sl.has_untracked_header()))
{
std::cout << treeclean_message << std::endl;
if (is_long)
{
std::cout << treeclean_message << std::endl;
}
}
}
63 changes: 40 additions & 23 deletions test/test_init.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
from pathlib import Path
import subprocess
from pathlib import Path


def test_init_in_directory(git2cpp_path, tmp_path):
# tmp_path exists and is empty.
assert list(tmp_path.iterdir()) == []

cmd = [git2cpp_path, 'init', '--bare', str(tmp_path)]
cmd = [git2cpp_path, "init", "--bare", str(tmp_path)]
p = subprocess.run(cmd, capture_output=True)
assert p.returncode == 0
assert p.stdout == b''
assert p.stderr == b''
assert p.stdout == b""
assert p.stderr == b""

assert sorted(map(lambda path: path.name, tmp_path.iterdir())) == [
'HEAD', 'config', 'description', 'hooks', 'info', 'objects', 'refs'
"HEAD",
"config",
"description",
"hooks",
"info",
"objects",
"refs",
]

# TODO: check this is a valid git repo
Expand All @@ -24,14 +30,20 @@ def test_init_in_cwd(git2cpp_path, tmp_path, run_in_tmp_path):
assert list(tmp_path.iterdir()) == []
assert Path.cwd() == tmp_path

cmd = [git2cpp_path, 'init', '--bare']
cmd = [git2cpp_path, "init", "--bare"]
p = subprocess.run(cmd, capture_output=True)
assert p.returncode == 0
assert p.stdout == b''
assert p.stderr == b''
assert p.stdout == b""
assert p.stderr == b""

assert sorted(map(lambda path: path.name, tmp_path.iterdir())) == [
'HEAD', 'config', 'description', 'hooks', 'info', 'objects', 'refs'
"HEAD",
"config",
"description",
"hooks",
"info",
"objects",
"refs",
]

# TODO: check this is a valid git repo
Expand All @@ -41,38 +53,43 @@ def test_init_not_bare(git2cpp_path, tmp_path):
# tmp_path exists and is empty.
assert list(tmp_path.iterdir()) == []

cmd = [git2cpp_path, 'init', '.']
cmd = [git2cpp_path, "init", "."]
p = subprocess.run(cmd, capture_output=True, cwd=tmp_path)
assert p.returncode == 0
assert p.stdout == b''
assert p.stderr == b''
assert p.stdout == b""
assert p.stderr == b""

# Directory contains just .git directory.
assert sorted(map(lambda path: path.name, tmp_path.iterdir())) == ['.git']
# Directory contains just .git directory.
assert sorted(map(lambda path: path.name, tmp_path.iterdir())) == [".git"]
# .git directory is a valid repo.
assert sorted(map(lambda path: path.name, (tmp_path / '.git').iterdir())) == [
'HEAD', 'config', 'description', 'hooks', 'info', 'objects', 'refs'
assert sorted(map(lambda path: path.name, (tmp_path / ".git").iterdir())) == [
"HEAD",
"config",
"description",
"hooks",
"info",
"objects",
"refs",
]

# Would like to use `git2cpp status` but it complains that 'refs/heads/master' not found
cmd = [git2cpp_path, 'log']
cmd = [git2cpp_path, "log"]
p = subprocess.run(cmd, capture_output=True, cwd=tmp_path)
assert p.returncode == 0
assert p.stdout == b''
assert p.stderr == b''
assert b"does not have any commits yet" in p.stdout


def test_error_on_unknown_option(git2cpp_path):
cmd = [git2cpp_path, 'init', '--unknown']
cmd = [git2cpp_path, "init", "--unknown"]
p = subprocess.run(cmd, capture_output=True)
assert p.returncode == 109
assert p.stdout == b''
assert p.stdout == b""
assert p.stderr.startswith(b"The following argument was not expected: --unknown")


def test_error_on_repeated_directory(git2cpp_path):
cmd = [git2cpp_path, 'init', 'abc', 'def']
cmd = [git2cpp_path, "init", "abc", "def"]
p = subprocess.run(cmd, capture_output=True)
assert p.returncode == 109
assert p.stdout == b''
assert p.stdout == b""
assert p.stderr.startswith(b"The following argument was not expected: def")
35 changes: 19 additions & 16 deletions test/test_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ def test_status_new_file(xtl_clone, git2cpp_path, tmp_path, short_flag, long_fla
assert (tmp_path / "xtl").exists()
xtl_path = tmp_path / "xtl"

p = xtl_path / "mook_file.txt" # Untracked files
p.write_text('')
p = xtl_path / "mook_file.txt" # Untracked files
p.write_text("")

pw = xtl_path / "CMakeLists.txt" # Changes not staged for commit / modified
pw = xtl_path / "CMakeLists.txt" # Changes not staged for commit / modified
pw.write_text("blablabla")

os.remove(xtl_path / "README.md") # Changes not staged for commit / deleted
os.remove(xtl_path / "README.md") # Changes not staged for commit / deleted

cmd = [git2cpp_path, 'status']
cmd = [git2cpp_path, "status"]
if short_flag != "":
cmd.append(short_flag)
if long_flag != "":
Expand All @@ -38,27 +38,29 @@ def test_status_new_file(xtl_clone, git2cpp_path, tmp_path, short_flag, long_fla
assert " D " in p.stdout
assert "?? " in p.stdout


def test_status_nogit(git2cpp_path, tmp_path):
cmd = [git2cpp_path, 'status']
cmd = [git2cpp_path, "status"]
p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
assert p.returncode != 0


@pytest.mark.parametrize("short_flag", ["", "-s", "--short"])
@pytest.mark.parametrize("long_flag", ["", "--long"])
def test_status_add_file(xtl_clone, git2cpp_path, tmp_path, short_flag, long_flag):
assert (tmp_path / "xtl").exists()
xtl_path = tmp_path / "xtl"

p = xtl_path / "mook_file.txt" # Changes to be committed / new file
p.write_text('')
p = xtl_path / "mook_file.txt" # Changes to be committed / new file
p.write_text("")

os.remove(xtl_path / "README.md") # Changes to be committed / deleted
os.remove(xtl_path / "README.md") # Changes to be committed / deleted

cmd_add = [git2cpp_path, 'add', "--all"]
cmd_add = [git2cpp_path, "add", "--all"]
p_add = subprocess.run(cmd_add, cwd=xtl_path, text=True)
assert p_add.returncode == 0

cmd_status = [git2cpp_path, 'status']
cmd_status = [git2cpp_path, "status"]
if short_flag != "":
cmd_status.append(short_flag)
if long_flag != "":
Expand All @@ -77,14 +79,15 @@ def test_status_add_file(xtl_clone, git2cpp_path, tmp_path, short_flag, long_fla
assert "A " in p_status.stdout
assert "D " in p_status.stdout


def test_status_new_repo(git2cpp_path, tmp_path, run_in_tmp_path):
# tmp_path exists and is empty.
assert list(tmp_path.iterdir()) == []

cmd = [git2cpp_path, 'init']
p = subprocess.run(cmd, cwd = tmp_path)

status_cmd = [git2cpp_path, 'status']
p_status = subprocess.run(status_cmd, cwd = tmp_path)
cmd = [git2cpp_path, "init"]
p = subprocess.run(cmd, cwd=tmp_path)
assert p.returncode == 0

status_cmd = [git2cpp_path, "status"]
p_status = subprocess.run(status_cmd, cwd=tmp_path)
assert p_status.returncode == 0