2012/08/10

git知识测试题—答案及解析

首先给出答案:ABCD BCDA CDAB DABC ABCD

解答如下:

题目1
这种情况往往是修改了工作区的文件,但是没有运行git add来将修改的文件添加到index中。正确方法为git add需要commit的文件,再执行git commit。
git commit --allow-empty只会创建一个空提交,工作区的内容仍旧未提交至git repo里。
git commit -a 会直接提交所有修改/删除的文件,通常不推荐此操作,因为很可能会将尚未ready的改变一并提交至git仓库。
git commit --amend 会进行一次修补提交,即不会产生一个新的commit,而是将此次commit的change直接apply到最近一次提交,提交相关信息不变。

题目2
git reset -- hello.c 只能恢复index中的文件,工作区的文件并不会被重置。
git checkout HEAD -- hello.c 同时恢复index与工作区中的文件。
git revert hello.c 非法操作
git update hello.c 非法操作

题目3
每次执行git add时,git会将修改过的文件以一个新object的形式加入到git仓库中,因此,如果此时执行git reset --hard,则这些新加入的object已经不被任何commit引用(包括index),此时运行git fsck会发现,每一次git add操作添加的文件版本都会显示为一个dangling object。

题目4
git add -A 添加所有文件,包括新添加的文件。
git add -p 通过逐一检查工作区文件与index文件diff输出来决定是否添加文件。
git add -i 交互式的选择要git add的文件。
git add -u 添加所有修改的文件,不包括新添加的文件。

题目5
git reset --hard 会重置当前branch
git checkout 只会改变HEAD,不会影响当前branch
git rebase 会嫁接连续的rev list到new base,进而改变历史
git commit --amend 会修改最近一次commit

题目6
这里的主要区别在于使用.gitignore还是.git/info/exclude。两者的主要区别在于.gitignore会被push到server上与其他人共享,而.git/info/exclude完全工作在本地。

题目7
git config --global core.autocrlf true 版本库中使用LF,而检出时始终使用CRLF。
git config --global core.autocrlf input 检出时始终使用LF。
在.gitattributes中设置* text=auto 如果core.eol未设置,则根据操作系统不同,在windows上使用CRLF,在linux上使用LF。

题目8
gitolite的写授权可以针对文件路径,分支。但是只有全局的读权限。

题目9
git revert 不会改变现有历史,而是生成一个新的commit来反转指定commit中的change。

题目10
git reset --hard 适用于要移除的commit为当前branch上最新的commit,否则会移除其他正确的commit。
git checkout 只会改变HEAD头,不会对branch历史修改。
git revert 可以撤销某个commit的change,但是不会在历史中删除该commit。

题目11
git reset -- filename 用于使用HEAD中的filename覆盖index中的版本。

题目12
参考git help describe

题目13
git clone会fetch所有远程branch到本地,但只有远程仓库HEAD指向的branch会在本地checkout。

题目14
使用git push origin :XX可以删除远程仓库中的XX分支。
git branch -D xx 无法删除当前所在分支。
默认执行git fetch,只会fetch远程仓库存在的分支。
默认执行git push,只会push在远程仓库存在对应分支的本地分支。
关于git pull/git push的默认操作,请参考我的另一篇文章 http://loveky2012.blogspot.com/2012/08/default-behaviour-of-git-pull-and-git-push.html

题目15
git rev-list master..maint 会输出所有出现在maint历史中但未出现再master历史中的commit列表。如果列表为空则表示master分支已经包含所有maint上的bugfix。
git log master..maint 原理同上。
在maint分支上执行git merge --ff-only master成功表示在master分支的历史中已经包含了maint分支上的change,因此此时merge master分支可以直接移动maint分支指向的commit进行快进合并。

题目16
当目录merge出现confilct时,可以使用git ls-files -s查看当前staged的object的状态。
263 gewang@LM-SHC-00355679@13:55:04:~/test/show
=> git merge master
Auto-merging test
CONFLICT (content): Merge conflict in test
Automatic merge failed; fix conflicts and then commit the result.
264 gewang@LM-SHC-00355679@13:55:07:~/test/show
=> git ls-files -s
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 aaa
100644 388ddf68417917d4c0e0faa74432c1c2e74d572e 1 test
100644 733205e05f85d7b51b96cbef2938d61bf304798b 2 test
100644 23bc1c902ffde28525f215cd2bfc44b6f4222709 3 test
可以看到test文件出现了3个stage的状态,分别为1,2,3。而没有出现冲突的文件的stage状态为0.
针对存在confilict的文件可以:
git show :1:test  # 查看冲突文件的common ancester版本
git show :2:test  # 查看本地branch中的版本
git show :3:test  # 查看远程branch中的版本

题目17
git config --global push.default upstream 不带参数push是仅推送当前branch
git config --global pull.rebase true 在执行git pull时,将远程分支获取到本地后使用rebase,而不是merge来将远程change应用到本地分支。
git config --global receive.denyDeletes true 设置此选项则git-receive-pack不会响应分支删除操作。

题目18
git gc会调用git reflog expire --all,而git reflog expire默认只会删除90天前的记录。如果想即使生效,则应该使用git reflog expire --expire=now --all。

题目19
详情请参考submodule文档。

题目20
用过JIRA,Redmine之类工具的都懂得。。。

没有评论:

发表评论