Skip to content

Commit

Permalink
[feat][command] implements update-index
Browse files Browse the repository at this point in the history
  • Loading branch information
smd1121 committed Jan 7, 2024
1 parent 5d03e12 commit 2399480
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 1 deletion.
4 changes: 3 additions & 1 deletion xgit/cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import typer

from xgit.commands import init, cat_file, ls_files, show_index, hash_object
from xgit.commands import init, cat_file, ls_files, show_index, hash_object, update_index

app = typer.Typer(add_completion=False, rich_markup_mode="markdown")

Expand All @@ -9,6 +9,8 @@
app.command()(init.init)
app.command()(cat_file.cat_file)
app.command()(ls_files.ls_files)
app.command()(update_index.update_index)

app.command(hidden=True)(show_index.show_index)


Expand Down
78 changes: 78 additions & 0 deletions xgit/commands/update_index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import sys
from pathlib import Path

import typer
from typer import Option, Argument
from typing_extensions import Optional, Annotated

from xgit.types.index import get_index
from xgit.utils.utils import find_repo


def update_index(
files: Annotated[Optional[list[str]], Argument(help="要更新的文件")] = None,
add: Annotated[bool, Option("--add", help="如果文件在暂存区中不存在,则加入暂存区")] = False,
remove: Annotated[bool, Option("--remove", help="如果文件在暂存区存在,但在本地不存在,则从暂存区移除")] = False,
force_remove: Annotated[bool, Option("--force-remove", help="从暂存区移除文件,即使文件在本地存在")] = False,
refresh: Annotated[bool, Option("--refresh", help="检查当前 index 中的文件是否需要 merge 或 update")] = False,
verbose: Annotated[bool, Option("-v", help="详细输出添加和删除的文件")] = False,
cacheinfo: Annotated[
Optional[list[str]], Option("--cacheinfo", help="与 `--add` 一同使用,用 `<mode>,<object>,<path>` 指定一个 blob 加入暂存区")
] = None,
):
"""
更新暂存区
"""
# 如果没有 git repo,会报错
index = get_index()

# === 检查参数正确性 ===
# add, remove, force_remove, refresh 互斥
if add + remove + force_remove + refresh > 1:
typer.echo("fatal: only one of the options can be used", err=True)
sys.exit(1)

# refresh 不能与 files 同时使用
if refresh and files:
typer.echo("fatal: --refresh cannot be used with files", err=True)
sys.exit(1)

# cacheinfo 必须与 add 同时使用
if cacheinfo and not add:
typer.echo("fatal: --cacheinfo can only be used with --add", err=True)
sys.exit(1)

# files 中的路径会被 ignore;将 files 分为本地存在和本地不存在两部分
repo = find_repo().resolve()
files = files or []
update_files = []

for f in files:
file_path = Path(f).resolve()

if not file_path.is_relative_to(repo):
typer.echo(f"fatal: '{f}' is outside repository at '{repo}'", err=True)
sys.exit(128)
elif file_path.is_dir():
typer.echo(f"Ignoring path '{f}'", err=True)
else:
update_files.append(f)


# === 执行操作 ===
# refresh:刷新 index 中的 metadata,报告需要 update 的文件
# 我们暂时忽略 merge 相关的状态
if refresh:
# 对于 index 中的每个 entry,检查其 metadata 是否与本地一致
# 如果不一致,检查文件 sha 是否一致:如果一致,更新 metadata;否则报告 needs update
pass

# 如果没有 add, remove, force_remove
if not (add or remove or force_remove):
# 对于 files 中的每一项
# 如果本地或 index 不存在,报错
# 如果都存在,更新其状态
pass



11 changes: 11 additions & 0 deletions xgit/types/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,19 @@ def __rich_repr__(self):
yield "entries", self.entries
yield "extensions", self.extensions

def update_or_add(self, entry: IndexEntry):
for i, e in enumerate(self.entries):
if e.file_name == entry.file_name:
self.entries[i] = entry
return
self.entries.append(entry)


def get_index() -> Index:
"""
如果 repo 不存在,报错退出
如果 index 不存在,返回没有 entry 的 Index 对象
"""
index_path = find_repo() / GIT_DIR / "index"
if not index_path.exists():
return Index()
Expand Down

0 comments on commit 2399480

Please sign in to comment.