Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ url: "https://github.com/BHFock/git-cl"
repository-code: "https://github.com/BHFock/git-cl"
license: BSD-3-Clause
doi: "10.5281/zenodo.18722077"
version: "1.1.3"
date-released: "2026-02-27"
version: "1.1.5"
date-released: "2026-04-16"
abstract: >-
git-cl is a command-line tool that brings changelist support to Git.
It introduces a pre-staging layer that allows developers to partition
Expand Down
35 changes: 30 additions & 5 deletions git-cl
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Single file, zero dependencies beyond Python 3.9+ and Git.
Cross-platform: Unix (fcntl) and Windows (msvcrt) file locking.
"""

__version__ = "1.1.4"
__version__ = "1.1.5"

import argparse
import datetime
Expand Down Expand Up @@ -624,6 +624,27 @@ def clutil_is_file_untracked(
return False


def clutil_is_file_untracked_cached(
file_path_rel_to_git_root: str,
status_map: dict[str, str]) -> bool:
"""
Check if a file is untracked using a precomputed status map.

This is a faster alternative to clutil_is_file_untracked for use
inside loops, avoiding a separate `git status` shellout per file.
The caller is responsible for obtaining the status map once via
clutil_get_file_status_map(show_all=True) before the loop.

Args:
file_path_rel_to_git_root: File path relative to git repository root
status_map: Precomputed status map from clutil_get_file_status_map

Returns:
True if the file is untracked, False otherwise.
"""
return status_map.get(file_path_rel_to_git_root, " ") == "??"


def clutil_get_stash_file() -> Path:
"""
Returns the path to the stash metadata file inside the Git directory.
Expand Down Expand Up @@ -2322,6 +2343,9 @@ def cl_stage(args: argparse.Namespace) -> None:
git_root = clutil_get_git_root()
to_stage = []

# Fetch git status once and reuse for all files in the changelist
status_map = clutil_get_file_status_map(show_all=True)

for stored_path in changelists[name]:
# Convert stored path (relative to git root) to absolute path
abs_path = (git_root / stored_path).resolve()
Expand All @@ -2333,8 +2357,7 @@ def cl_stage(args: argparse.Namespace) -> None:
# Convert to path relative to current working directory for Git command
rel_to_cwd = _relpath(abs_path, Path.cwd().resolve())

# Check if this file is tracked (not untracked)
if not clutil_is_file_untracked(stored_path, git_root):
if not clutil_is_file_untracked_cached(stored_path, status_map):
to_stage.append(rel_to_cwd)

if not to_stage:
Expand Down Expand Up @@ -2714,6 +2737,9 @@ def cl_commit(args: argparse.Namespace) -> None:
git_root = clutil_get_git_root()
to_commit = []

# Fetch git status once and reuse for all files in the changelist
status_map = clutil_get_file_status_map(show_all=True)

for stored_path in changelists[name]:
# Convert stored path (relative to git root) to absolute path
abs_path = (git_root / stored_path).resolve()
Expand All @@ -2725,8 +2751,7 @@ def cl_commit(args: argparse.Namespace) -> None:
# Convert to path relative to current working directory for Git command
rel_to_cwd = _relpath(abs_path, Path.cwd().resolve())

# Check if this file is tracked (not untracked)
if not clutil_is_file_untracked(stored_path, git_root):
if not clutil_is_file_untracked_cached(stored_path, status_map):
to_commit.append(rel_to_cwd)

if not to_commit:
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = git-changelists
version = 1.1.3
version = 1.1.5
author = Bjoern Hendrik Fock
description = Git subcommand for named changelist support. Group working directory files by intent, then stage, commit, or branch by changelist.
long_description = file: README.md
Expand Down
Loading