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
|
||||
|
||||
def __init__(self, path, force=False):
|
||||
self.worktree = path
|
||||
self.worktree = path.replace("\\", "/")
|
||||
self.gitdir = join_path(path, ".git")
|
||||
|
||||
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.
|
||||
if not check_ignore(ignore, 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