Lab0实验报告
一、实验思考题
Thinking0.1
在/home/20xxxxxx/learnGit目录下创建一个名为README.txt的文件。这时使用 git status > Untracked.txt 。
在 README.txt 文件中随便写点什么,然后使用刚刚学到的 add 命令,再使用 git status > Stage.txt 。
之后使用上面学到的 Git 提交有关的知识把 README.txt 提交,并在提交说明里写入自己的学号。
使用 cat Untracked.txt 和 cat Stage.txt,对比一下两次的结果,体会一下README.txt 两次所处位置的不同。
修改 README.txt 文件,再使用 git status > Modified.txt 。
使用 cat Modified.txt ,观察它和第一次 add 之前的 status 一样吗,思考一 下为什么? (对于Thinking 0.1,只有这一小问需要写到课后的实验报告中)
答:不一样。第一次add之前,文件处于 untracked 状态,进行了add后,文件进入暂存区,此时处于stage状态,commit后进入版本库。在第二次修改了文件内容后,修改的是工作区的内容,暂存区的文件内容未被修改,文件处于modified状态,此时要用add指令将暂存区文件修改为stage状态。
Thinking0.2
仔细看看这张图,思考一下箭头中的 add the file、stage the file 和 commit 分别对应的是 Git 里的哪些命令呢?
答:add the file 对应的是git add
指令,表示跟踪文件;stage the file 对应的是git add
指令,表示修改后加入暂存区;commit 对应的是git commit -m "<message>"
。
Thinking0.3
深夜,小明在做操作系统实验。困意一阵阵袭来,小明睡倒在了键盘上。等到小明早上醒来的时候,他惊恐地发现,他把一个重要的代码文件printf.c删除掉了。苦恼的小明向你求助,你该怎样帮他把代码文件恢复呢?
答:使用git checkout -- printf.c
从暂存区中找回。
正在小明苦恼的时候,小红主动请缨帮小明解决问题。小红很爽快地在键盘上敲下了git rm printf.c,这下事情更复杂了,现在你又该如何处理才能弥补小红的过错呢?
答:首先使用git reset HEAD printf.c
重写暂存区的目录树,然后再使用git checkout -- printf.c
从暂存区找回文件。
处理完代码文件,你正打算去找小明说他的文件已经恢复了,但突然发现小明的仓库里有一个叫Tucao.txt,你好奇地打开一看,发现是吐槽操作系统实验的,且该文件已经被添加到暂存区了,面对这样的情况,你该如何设置才能使Tucao.txt在不从工作区删除的情况下不会被git commit指令提交到版本库?
答:使用git rm --cached printf.c
直接从暂存区删除文件,但是工作区保持不变。
Thinking0.4
找到我们在/home/20xxxxxx/learnGit下刚刚创建的README.txt,没有的话就新建一个。
在文件里加入Testing 1,add,commit,提交说明写 1。
模仿上述做法,把1分别改为 2 和 3,再提交两次。
使用 git log命令查看一下提交日志,看是否已经有三次提交了?记下提交说明为 3 的哈希值1。
开动时光机!使用 git reset --hard HEAD^ ,现在再使用git log,看看什么没了?
找到提交说明为1的哈希值,使用 git reset --hard ,再使用git log,看看什么没了?
现在我们已经回到过去了,为了再次回到未来,使用 git reset --hard ,再使用git log,我胡汉三又回来了!
这一部分在课后的思考题中简单写一写你的理解即可,毕竟能够进行版本的恢复是使用git很重要的一个原因。
答:Git版本库记录着每一次提交的版本,提交的哈希值为最近一次提交的哈希值。如用提交说明为1的哈希值,使用git reset,则会回到提交版本1和版本1以前的版本。如用提交说明为3的哈希值,则会到提交说明为3的版本,该版本以前的提交会在git log中。
Thinking0.5
思考下面四个描述,你觉得哪些正确,哪些错误,请给出你参考的资料或实验证据。
克隆时所有分支均被克隆,但只有HEAD指向的分支被检出。
答:正确。git clone
会默认克隆仓库的所有分支,但只有HEAD指向的分支被检出。
克隆出的工作区中执行 git log、git status、git checkout、git commit等操作不会去访问远程版本库。
答:正确。git log
、git status
、git checkout
、git commit
等操作均为对本地仓库的访问,而本地的仓库已从远程仓库中拉出。
克隆时只有远程版本库HEAD指向的分支被克隆。
答:错误。克隆时所有的分支都被克隆,但只有HEAD所指的分支被检出。
克隆后工作区的默认分支处于master分支。
答:正确。
Thinking0.6
执行如下命令,并查看结果
echo first
echo second > output.txt
echo third > output.txt
echo forth >> output.txt
答:执行echo first
时,直接在当前窗口输出了first;执行echo second > output.txt
后,在output.txt文件中输出了second;执行echo third > output.txt
后,在output.txt文件中输出了third,之前输出的second被覆盖掉了;执行echo forth >> output.txt
后,在output.txt文件中输出了forth,且之前输出的third并没有被覆盖。
由此可见>可以将输出的内容输出至指定文件,并且>在每次输出后执行覆盖输出,将之前文件中的内容替换掉,但>>不会替换掉之间内容。
Thinking0.7
使用你知道的方法(包括重定向)创建下图内容的文件(文件命名为test),将创建该文件的命令序列保存在command文件中,并将test文件作为批处理文件运行,将运行结果输出至result文件中。给出command文件和result文件的内容,并对最后的结果进行解释说明(可以从test文件的内容入手). 具体实现的过程中思考下列问题: echo echo Shell Start 与 echo 'echo Shell Start’效果是否有区别; echo echo $c>file1 与 echo 'echo $c>file1’效果是否有区别.
答:command文件中的代码如下:
echo echo Shell Start... > test
echo echo set a = 1 >> test
echo a=1 >> test
echo echo set b = 2 >> test
echo b=2 >> test
echo echo set c = a+b >> test
echo c=\$[\$a+\$b] >> test
echo echo c = \$c >> test
echo echo save c to ./file1 >> test
echo echo \$c\>file1 >> test
echo echo save b to ./file2 >> test
echo echo \$b\>file2 >> test
echo echo save a to ./file3 >> test
echo echo \$a\>file3 >> test
echo echo save file1 file2 file3 to file4 >> test
echo cat file1\>file4 >> test
echo cat file2\>\>file4 >> test
echo cat file3\>\>file4 >> test
echo echo save file4 to ./result >> test
echo cat file4\>\>result >> test
二、实验难点图示
本次实验遇到的难点在Exercise0.4的第二小题:
lab0工作区的csc/code/fibo.c成功更换字段后(bash modify.sh fibo.c char int),现已有csc/Makefile和csc/code/Makefile,补全两个Makefile文件,要求在csc目录下通过指令make可在csc/code文件夹中生成fibo.o、main.o,在csc文件夹中生成可执行文件fibo,再输入指令make clean后只删除两个.o文件。[注意:不能修改fibo.h和main.c文件中的内容,提交的文件中fibo.c必须是修改后正确的fibo.c,可执行文件fibo作用是从stdin输入一个整数n,可以输出斐波那契数列前n项,每一项之间用空格分开。比如n=5,输出1 1 2 3 5]
在解题时遇到的问题主要有以下几点:
- 没有理解题目中要求补全两个Makefile的意思,是看完讨论区同学的分享才知道需要用外层的Makefile去调用内层的Makefile。
- 外部Makefile调用内部Makefile时,不清楚一条指令执行完之后仍会跳回到当前目录,导致运行时出现反复跳入跳出死循环的情况。
- 没有弄明白include文件夹下的fibo.h和fibo.c以及main.c文件之间的关系,之后经过查阅资料明白include内的fibo.h相当于c代码的头文件,而fibo.c和main.c都是c代码的函数块,三者必须相关联才能生成可执行文件fibo.exe。
后来完成这道题的思路如下:
外层的Makefile内容:
fibo:
cd ./code && make fibo && gcc main.o fibo.o -o fibo
mv ./code/fibo .
clean:
cd ./code && make clean
内层的Makefile内容:
fibo:
gcc fibo.c -c -I ../include
gcc main.c -c -I ../include
clean:
rm fibo.o
rm main.o
三、体会与感想
lab0课下的教程学习、Exercise和实验报告大概花费了我十个小时左右的时间,因为命令行、vim这些东西几乎没有接触过,git也仅仅是在OO课学会了一点点,但仅仅会用不懂原理。
不过教程写的很详细,能感觉到完全是面对我这样的小白来做的,跟着教程学,确实能感受到这些知识其实很成体系,但是或许一下接受的内容太多,grep、sed那些大部分的命令还是记不住,希望能多加练习提升熟练度。
很多命令通过亲自的练习与实践能掌握的更透彻,但是由于对这些内容还不是很熟,加上没有图形化界面,所以很多时候还是很抓瞎,删除指令教程里反复强调要慎用,所以总是做的小心翼翼,很多时候建的文件一团糟还不敢乱删,所以接下来还是要继续熟悉各种工具尤其是git的使用,做出错误操作时能够有挽回的余地。
本次实验难度并不高,但是需要多花时间,才能为做好以后的实验打下基础。