GitHug

  • 1-5关 12.16

  • 6-11关 12.17


  1. 本文章仅记录githug过关经历。
    详细介绍及安装方法不在本文章范围之内,请自行解决。

  2. 本文首发于Cmd-Markdown,此处仅为md内容粘贴。
    如若有显示不全,图片缺失,乱码或排版问题请访问原发布地址。

目前为止,githug大部分问题查阅git book即可解决。

1 init

Name: init
Level: 1
Difficulty: *

A new directory, `git_hug`, has been created; initialize an empty repository in it.

参见gitbook-2.1

如果你打算使用 Git 来对现有的项目进行管理,你只需要进入该项目目录并输入:

$ git init

该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。

即为初始化一个空的仓库,git init 即可。

2 config

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 选项的命令来配置。

3 add

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命令可以将未跟踪的文件添加到暂存区。

gitbook-2.2-add 文件状态

  1. add
    git 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的更多信息

    > 这是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。 将这个命令理解为“添加内容到下一次提交中”而不是“将一个文件添加到项目中”要更加合适
    
  2. 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]

4 commit

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

5 clone

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.
检查连接... 完成。

6 clone to folder

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.
检查连接... 完成。

7 ignore

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结尾的文件。

gitbook-2.2-忽略文件

一般我们总会有些文件无需纳入 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

8 include

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

9 status

Name: status
Level: 9
Difficulty: *

There are some files in this repository, one of the files is untracked, which file is it?

gitbook-2.2-跟踪文件

一个新初始化的仓库内,所有文件都是未跟踪的(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

10 number of files commited

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

11 rm

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中删除呢?

gitbook-2.2-移除文件

要从 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

STooon
22 声望1 粉丝