1-5关 12.16c++
6-11关 12.17git
本文章仅记录githug过关经历。
详细介绍及安装方法不在本文章范围以内,请自行解决。github
本文首发于Cmd-Markdown,此处仅为md内容粘贴。
如如有显示不全,图片缺失,乱码或排版问题请访问原发布地址。vim
目前为止,githug大部分问题查阅git book便可解决。ruby
Name: init Level: 1 Difficulty: * A new directory, `git_hug`, has been created; initialize an empty repository in it.
参见gitbook-2.1ide
若是你打算使用 Git 来对现有的项目进行管理,你只须要进入该项目目录并输入:学习
$ git init
测试
该命令将建立一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中全部的必须文件,这些文件是 Git 仓库的骨干。ui
即为初始化一个空的仓库,git init
便可。this
Name: config Level: 2 Difficulty: * Set up your git name and email, this is important so that your commits can be identified.
设置用户名和email。用来标识主机。
使用githug hint 并查阅git book可知,
git book- 1.6
当安装完 Git 应该作的第一件事就是设置你的用户名称与邮件地址。 这样作很重要,由于每个 Git 的提交都会使用这些信息,而且它会写入到你的每一次提交中,不可更改:
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
再次强调,若是使用了 --global 选项,那么该命令只须要运行一次,由于以后不管你在该系统上作任何事情, Git 都会使用那些信息。 当你想针对特定项目使用不一样的用户名称与邮件地址时,能够在那个项目目录下运行没有 --global 选项的命令来配置。
Name: add Level: 3 Difficulty: * There is a file in your folder called `README`, you should add it to your staging area Note: You start each level with a new repo. Don't look for files from the previous one.
staging area是什么?
add 是什么操做?
学习完2.2天然能够明白这个题要求作什么,也能够回答这两个问题了。
staging area即为暂存区,add命令能够将未跟踪的文件添加到暂存区。
addgit add
能够经过参数控制,从而将指定文件添加到git控制中。
$ git add README $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README
关于git add
的更多信息
> 这是个多功能命令:能够用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。 将这个命令理解为“添加内容到下一次提交中”而不是“将一个文件添加到项目中”要更加合适
git系统中文件的全部状态
其次,从使用者的角度描述大体一下git系统中文件的全部状态首先对文件作出修改,在修改以前,文件天然处于未修改(unmodified)状态, 修改以后,天然处于已修改(modified)状态,这很好理解。而后将作出的改动提交(commit)到git,确认作出修改,提交历史记录中就多了一条。同时文件又返回未修改(unmodified)状态,也能够叫作,已提交状态
大体意思以下
版本 | 用户 | 说明 | 日期 |
---|---|---|---|
1 | 张三 | 删除了软件服务条款5 | 7/12 10:38 |
2 | 张三 | 增长了License人数限制 | 7/12 18:09 |
3 | 李四 | 财务部门调整了合同金额 | 7/13 9:51 |
4 | 张三 | 延长了免费升级周期 | 7/14 15:17 |
不过只有2种状态是否方便呢?是否能知足全部需求呢?
新添加的文件,应该处于什么状态呢?不该该是已提交,由于尚未提交过,可是已修改也不太对,尚未对文件作出修改呢
若是我今天进行了一些修改,可是一部份内容属于测试内容,不但愿提交该怎么办?
在cs领域有句名言
“计算机科学领域的任何问题均可以经过增长一个间接的中间层来解决”
“Any problem in computer science can be solved by anther layer of indirection.”
是时候学习文件的第三种状态了,暂存(staged),或者叫待提交。
这首先能够解决第一个问题,新加入git系统的文件应该处于暂存,这样就能够直接在下一次进行提交了,同时,这也符合git add命令的功能
其次,多了暂存这样一个中间状态,咱们就能够按照本身的需求将已经修改的文件添加到暂存区,
好比我修改了10个文件,但我只将其中的2个添加到暂存区(Changes to be committed)或者说待提交区。这样,下一次提交的时候,就只会将这两个文件进行提交。其他文件仍旧只是已修改。
如今这三个状态之间的关系是这样的:
A[未修改/已提交 ] -->|修改| B(已修改) B --> |暂存/add|C[暂存区/待提交] C --> |提交/commit|A
固然,若是只修改了一个文件,却打算提交,也能够跳过暂存区,直接提交。git commit -a
本节全部命令小结
$ git add $ git commit [-a]
Name: commit Level: 4 Difficulty: * The `README` file has been added to your staging area, now commit it.
通过上述的2.2大体学习,这一关就十分简单了,提交(commit)这个readme便可。
-> % git commit [master (根提交) b08b86e] this just is a test 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 README
Name: clone Level: 5 Difficulty: * Clone the repository at https://github.com/Gazler/cloneme.
参见 gitbook-2.1(其实clone应该和init放在一块儿的)
克隆仓库的命令格式是 git clone [url] 。 好比,要克隆 Git 的可连接库 libgit2,能够用下面的命令:
$ git clone https://github.com/libgit2/libgit2
这会在当前目录下建立一个名为 “libgit2” 的目录,并在这个目录下初始化一个 .git 文件夹,从远程仓库拉取下全部数据放入 .git 文件夹,而后从中读取最新版本的文件的拷贝。 若是你进入到这个新建的 libgit2 文件夹,你会发现全部的项目文件已经在里面了,准备就绪等待后续的开发和使用。 若是你想在克隆远程仓库的时候,自定义本地仓库的名字,你可使用以下命令:
$ git clone https://github.com/libgit2/libgit2 mylibgit
这将执行与上一个命令相同的操做,不过在本地建立的仓库名字变为 mylibgit。
按照gitbook进行操做便可克隆一个已有仓库。
-> % git clone https://github.com/Gazler/cloneme 正克隆到 'cloneme'... remote: Counting objects: 7, done. remote: Total 7 (delta 0), reused 0 (delta 0), pack-reused 7 Unpacking objects: 100% (7/7), done. 检查链接... 完成。
Name: clone_to_folder Level: 6 Difficulty: * Clone the repository at https://github.com/Gazler/cloneme to `my_cloned_repo`.
即为第5关中介绍的内容,克隆一个仓库到指定文件夹。
-> % git clone https://github.com/Gazler/cloneme my_cloned_repo 正克隆到 'my_cloned_repo'... remote: Counting objects: 7, done. remote: Total 7 (delta 0), reused 0 (delta 0), pack-reused 7 Unpacking objects: 100% (7/7), done. 检查链接... 完成。
Name: ignore Level: 7 Difficulty: ** The text editor 'vim' creates files ending in `.swp` (swap files) for all files that are currently open. We don't want them creeping into the repository. Make this repository ignore `.swp` files.
vim 会为正在编辑的文件生成.swp
文件,对这类临时文件进行版本控制是无心义的,也不须要显示出来。因此请忽视以.swp
结尾的文件。
通常咱们总会有些文件无需归入 Git 的管理,也不但愿它们总出如今未跟踪文件列表。 一般都是些自动生成的文件,好比日志文件,或者编译过程当中建立的临时文件等。 在这种状况下,咱们能够建立一个名为 .gitignore 的文件,列出要忽略的文件模式。
如下是一些规范和详细的例子
全部空行或者以 # 开头的行都会被 Git 忽略。
可使用标准的 glob 模式匹配。
匹配模式能够以(/)开头防止递归。
匹配模式能够以(/)结尾指定目录。
要忽略指定模式之外的文件或目录,能够在模式前加上惊叹号(!)取反。
glob模式解释
星号(
*
)匹配零个或多个任意字符;[abc] 匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);
问号(?)只匹配一个任意字符;
若是在方括号中使用短划线分隔两个字符,表示全部在这两个字符范围内的均可以匹配(好比 [0-9] 表示匹配全部 0 到 9 的数字)。
使用两个星号(
*
) 表示匹配任意中间目录,好比a/**/z 能够匹配 a/z, a/b/z 或 a/b/c/z等。
一些例子
# no .a files *.a # but do track lib.a, even though you're ignoring .a files above !lib.a # only ignore the TODO file in the current directory, not subdir/TODO /TODO # ignore all files in the build/ directory build/ # ignore doc/notes.txt, but not doc/server/arch.txt doc/*.txt # ignore all .pdf files in the doc/ directory doc/**/*.pdf
因此按照要求忽略.swp
便可。使用 *.swp
便可匹配。
-> % cat .gitignore .profile.yml .gitignore *.swp
Name: include Level: 8 Difficulty: ** Notice a few files with the '.a' extension. We want git to ignore all but the 'lib.a' file.
忽视全部.a
文件,除了lib.a
。
根据第七关在2.2所学的内容便可写出匹配模式。*.a
即会匹配全部.a
文件,接下来须要不匹配lib.a
文件。
采用!
便可,也就是!lib.a
。
-> % cat .gitignore .profile.yml .gitignore *.a !lib.a
Name: status Level: 9 Difficulty: * There are some files in this repository, one of the files is untracked, which file is it?
一个新初始化的仓库内,全部文件都是未跟踪的(untracked)。即为没有归入git。
显而易见,不是全部的文件都须要归入版本控制,好比c或者c++的.o
文件,或者其余语言的中间生成文件,以及一些配置文件,与项目内容没有直接关系,并且能够生成,彻底不须要归入版本控制。git status
能够查看当前全部文件的状态, untracked即为未跟踪
Untracked files: (use "git add <file>..." to include in what will be committed) README
使用git status便可轻易解决此问题,database.yml未跟踪
-> % git status 位于分支 master 初始提交 要提交的变动: (使用 "git rm --cached <文件>..." 以取消暂存) 新文件: Guardfile 新文件: README 新文件: config.rb 新文件: deploy.rb 新文件: setup.rb 未跟踪的文件: (使用 "git add <文件>..." 以包含要提交的内容) database.yml
Name: number_of_files_committed Level: 10 Difficulty: * There are some files in this repository, how many of the files will be committed?
这个仓库里有数个文件,那么将要提交的文件有多少个?
要提交的文件,也就是暂存区的文件,新添加的文件会在暂存区内,修改过并add的文件也在暂存区内。
使用git status便可获知有多少个文件待提交。
-> % git status 位于分支 master 要提交的变动: (使用 "git reset HEAD <文件>..." 以取消暂存) 新文件: rubyfile1.rb 修改: rubyfile4.rb 还没有暂存以备提交的变动: (使用 "git add <文件>..." 更新要提交的内容) (使用 "git checkout -- <文件>..." 丢弃工做区的改动) 修改: rubyfile5.rb 未跟踪的文件: (使用 "git add <文件>..." 以包含要提交的内容) rubyfile6.rb rubyfile7.rb
Name: rm Level: 11 Difficulty: ** A file has been removed from the working tree, however the file was not removed from the repository. Find out what this file was and remove it.
一个文件已经从工做目录中删除了,可是它却没有从git仓库中删除,请找出这个文件,并删除它。
git仓库中存储的是什么呢?为何文件删除了,却没有从git系统中删除?
先使用git status
看看状况吧
-> % git status 位于分支 master 还没有暂存以备提交的变动: (使用 "git add/rm <文件>..." 更新要提交的内容) (使用 "git checkout -- <文件>..." 丢弃工做区的改动) 删除: deleteme.rb 修改还没有加入提交(使用 "git add" 和/或 "git commit -a")
查看得知,确实有一个文件被删除了,可是却能够在git中看到
那么问题来了,如何将一个文件从git中删除呢?
要从 Git 中移除某个文件,就必需要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),而后提交。 能够用 git rm 命令完成此项工做,并连带从工做目录中删除指定的文件,这样之后就不会出如今未跟踪文件清单中了。
若是只是简单地从工做目录中手工删除文件,运行 git status 时就会在 “Changes not staged for commit” 部分(也就是 未暂存清单)看到:
$ rm PROJECTS.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: PROJECTS.md no changes added to commit (use "git add" and/or "git commit -a")
而后再运行 git rm 记录这次移除文件的操做:
$ git rm PROJECTS.md rm 'PROJECTS.md' $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: PROJECTS.md
下一次提交时,该文件就再也不归入版本管理了。
按照上述内容操做便可。
-> % git rm deleteme.rb rm 'deleteme.rb' -> % git status 位于分支 master 要提交的变动: (使用 "git reset HEAD <文件>..." 以取消暂存) 删除: deleteme.rb