COMP(2041|9044) - 24T1
COMP(2041|9044) 24T1 — Assignment 1: Pushy
Subset 0详解
这项作业要求你实现一个名为 "Pushy" 的简化版的版本控制系统,它被设计为一个子集模式的Git,目的是为了给你提供Shell编程的实践以及对Git核心语义的深刻理解。作业不仅需要在讲座笔记基础上寻找Shell及Git的在线文档来完成,而且还需要你通过对参考实现(reference implementation)的行为匹配来满足要求。
作业主要要求如下:
- 实现10个简化的Git核心命令:
pushy-init
:创建一个空的Pushy仓库。pushy-add
:将一个或多个文件的内容添加到索引中。pushy-commit -m 'message'
:保存索引中所有文件的副本到仓库,并附带一个描述性的提交信息。pushy-log
:打印出所有提交的日志。pushy-show [commit]:filename
:打印指定提交或索引的指定文件的内容。- ...以及其他5个命令。
-
提交编号: 提交应当按照顺序进行编号。
-
错误信息: 实现的脚本应当产生和参考实现相同的错误信息。
-
POSIX兼容: 所有脚本必须是POSIX兼容的Shell。
-
参考实现: 命令的很多方面并没有在作业文档中明确说明,因此需要参照参考实现的行为。
-
简化假设: 在实现的过程中,你将会用到一些简化的假设,这会使得任务变得更加容易。
下面是对个别命令更具体的要求:
pushy-init
:创建名为.pushy
的目录作为仓库,如果目录已存在或无法创建,输出错误信息。pushy-add filenames...
:需要处理文件并存放在.pushy
目录下的合适位置,只能添加当前目录下的普通文件。pushy-commit -m message
:需要记录每一次提交的编号和消息,并且这些编号是顺序的。提交信息不包含新行。pushy-log
:每行输出一个提交信息,包含编号和提交消息。pushy-show [commit]:filename
:输出指定提交编号的文件内容,如果没有指定提交编号,则输出索引中该文件的内容。
最后,作业提供了一些示例,说明了上述命令如何被执行和期望的输出,这能帮助你更好地理解每个命令的具体要求。作业要求你熟悉Shell语法和Git的工作原理,同时也需要具备查阅文档和参考现有实现的能力。
脚本1:pushy-init
第一个Shell脚本是 pushy-init
,它的作用是创建一个空的Pushy仓库。这个脚本简单地建立了版本控制系统的初始化环境。具体要求如下:
- 创建一个名为
.pushy
的目录,这个目录将被用来存储仓库的相关信息。 - 如果
.pushy
目录已经存在或者无法被创建,应当输出错误信息。 - 脚本应当匹配参考实现的行为,包括输出的错误消息。
以下是 pushy-init
的Shell脚本实现代码:
#!/bin/sh
# pushy-init - 创建一个空的Pushy仓库
# 检查是否已存在.pushy目录
if [ -d ".pushy" ]; then
echo "./pushy-init: error: .pushy already exists" >&2
exit 1
fi
# 尝试创建.pushy目录
if mkdir ".pushy"; then
echo "Initialized empty pushy repository in .pushy"
else
echo "Error: Unable to create directory .pushy" >&2
exit 1
fi
这段代码首先检查当前目录下是否存在 .pushy
目录,如果目录已存在,打印错误信息并退出。如果目录不存在,尝试创建 .pushy
目录并打印成功初始化的信息。如果创建目录失败,例如由于权限问题,则打印错误信息并退出。脚本中 >&2
表示将错误信息输出到标准错误输出。
脚本2:pushy-add
第二个Shell脚本是 pushy-add
,其功能是将一个或多个文件的内容加入到索引中,作为准备提交到仓库(repository)的一步。
具体要求如下:
- 仅支持在当前目录下添加普通文件,不处理包含斜杠(/)的路径。
- 可接受的文件名以字母或数字开头,仅包含字母、数字、点(.)、减号(-)和下划线(_)。
- 需要有一种方式在
.pushy
子目录中存储待索引的文件。
以下是 pushy-add
的Shell脚本实现代码:
#!/bin/sh
# pushy-add - 将文件内容添加到索引中
INDEX_DIR=".pushy/index" # 索引文件存放的位置
# 检查.pushy目录是否存在
if [ ! -d ".pushy" ]; then
echo "Error: Pushy repository not initialized. You must run pushy-ini