Add 'rm' command
This commit is contained in:
parent
bad433b264
commit
326864ecda
96
libwyag.py
96
libwyag.py
@ -48,7 +48,7 @@ class GitRepository (object):
|
|||||||
conf = None
|
conf = None
|
||||||
|
|
||||||
def __init__(self, path, force=False):
|
def __init__(self, path, force=False):
|
||||||
self.worktree = path
|
self.worktree = path.replace("\\", "/")
|
||||||
self.gitdir = join_path(path, ".git")
|
self.gitdir = join_path(path, ".git")
|
||||||
|
|
||||||
if not (force or os.path.isdir(self.gitdir)):
|
if not (force or os.path.isdir(self.gitdir)):
|
||||||
@ -1197,3 +1197,97 @@ def cmd_status_index_worktree(repo, index):
|
|||||||
# its name without its contents.
|
# its name without its contents.
|
||||||
if not check_ignore(ignore, f):
|
if not check_ignore(ignore, f):
|
||||||
print(" ", f)
|
print(" ", f)
|
||||||
|
|
||||||
|
def index_write(repo, index):
|
||||||
|
with open(GitRepository.repo_file(repo, "index"), "wb") as f:
|
||||||
|
|
||||||
|
# Header
|
||||||
|
|
||||||
|
# Magic bytes which identify the file type.
|
||||||
|
f.write(b"DIRC")
|
||||||
|
f.write(index.version.to_bytes(4, "big"))
|
||||||
|
f.write(len(index.entries).to_bytes(4, "big"))
|
||||||
|
|
||||||
|
# Entries
|
||||||
|
|
||||||
|
idx = 0
|
||||||
|
for e in index.entries:
|
||||||
|
f.write(e.ctime[0].to_bytes(4, "big"))
|
||||||
|
f.write(e.ctime[1].to_bytes(4, "big"))
|
||||||
|
f.write(e.mtime[0].to_bytes(4, "big"))
|
||||||
|
f.write(e.mtime[1].to_bytes(4, "big"))
|
||||||
|
f.write(e.dev.to_bytes(4, "big"))
|
||||||
|
f.write(e.ino.to_bytes(4, "big"))
|
||||||
|
|
||||||
|
mode = (e.mode_type << 12) | e.mode_perms
|
||||||
|
f.write(mode.to_bytes(4, "big"))
|
||||||
|
|
||||||
|
f.write(e.uid.to_bytes(4, "big"))
|
||||||
|
# FIXME: Convert back to int.
|
||||||
|
f.write(int(e.sha, 16).to_bytes(20, "big"))
|
||||||
|
|
||||||
|
flag_assume_valid = 0x1 << 15 if e.flag_assume_valid else 0
|
||||||
|
|
||||||
|
name_bytes = e.name.encode("utf8")
|
||||||
|
bytes_len = len(name_bytes)
|
||||||
|
if bytes_len >= 0xFFF:
|
||||||
|
name_length = 0xFFF
|
||||||
|
else:
|
||||||
|
name_length = bytes_len
|
||||||
|
|
||||||
|
f.write((flag_assume_valid | e.flag_stage | name_length).to_bytes(2, "big"))
|
||||||
|
|
||||||
|
f.write(name_bytes)
|
||||||
|
# Null-terminate the name string
|
||||||
|
f.write((0).to_bytes(1, "big"))
|
||||||
|
|
||||||
|
idx += 62 + len(name_bytes) + 1
|
||||||
|
|
||||||
|
# Add padding if necessary
|
||||||
|
if idx % 8 != 0:
|
||||||
|
pad = 8 - (idx % 8)
|
||||||
|
f.write((0).to_bytes(pad, "big"))
|
||||||
|
idx += pad
|
||||||
|
|
||||||
|
argsp = argsubparsers.add_parser("rm", help="Remove files from the working tree and the index.")
|
||||||
|
argsp.add_argument("path", nargs="+", help="Files to remove")
|
||||||
|
|
||||||
|
def cmd_rm(args):
|
||||||
|
repo = repo_find()
|
||||||
|
rm(repo, args.path)
|
||||||
|
|
||||||
|
def rm(repo, paths, delete=True, skip_missing=False):
|
||||||
|
index = index_read(repo)
|
||||||
|
|
||||||
|
worktree = repo.worktree.replace("\\", "/") + "/"
|
||||||
|
|
||||||
|
# Make paths absolute
|
||||||
|
abspaths = list()
|
||||||
|
for path in paths:
|
||||||
|
abspath = os.path.abspath(path).replace("\\", "/")
|
||||||
|
if abspath.startswith(worktree):
|
||||||
|
abspaths.append(abspath)
|
||||||
|
else:
|
||||||
|
raise Exception(f"Cannot remove paths outside of worktree: {path}")
|
||||||
|
|
||||||
|
kept_entries = list()
|
||||||
|
remove = list()
|
||||||
|
|
||||||
|
for e in index.entries:
|
||||||
|
full_path = join_path(repo.worktree, e.name)
|
||||||
|
|
||||||
|
if full_path in abspaths:
|
||||||
|
remove.append(full_path)
|
||||||
|
abspaths.remove(full_path)
|
||||||
|
else:
|
||||||
|
kept_entries.append(e)
|
||||||
|
|
||||||
|
if len(abspaths) > 0 and not skip_missing:
|
||||||
|
raise Exception(f"Cannot remove paths not in the index: {abspaths}")
|
||||||
|
|
||||||
|
if delete:
|
||||||
|
for path in remove:
|
||||||
|
os.unlink(path)
|
||||||
|
|
||||||
|
index.entries = kept_entries
|
||||||
|
index_write(repo, index)
|
||||||
|
Loading…
Reference in New Issue
Block a user