Prog Git 第二章 git 基础

2.1 获取 Git 仓库

在现有目录初始化仓库

1
git init

命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。此时这些文件还处于未被跟踪状态,需要执行git add 命令来对文件进行跟踪,然后执行 git commit 进行提交。

1
2
3
4
git add .
git add README.txt
git commit
git commit -m "init version control"

克隆已有仓库

使用git clone 命令就可以将远程服务器的所有代码克隆到本地,命令格式是git clone [url]

1
git clone https://github.com/libgit2/libgit2

如果想自定义本地仓库的名字,命令如下:

1
$ git clone https://github.com/libgit2/libgit2 mylibgit

此时就会在本地新建一个 mylibgit 的文件夹。

Git 支持多种数据传输协议。 上面的例子使用的是 https:// 协议,不过你也可以使用 git:// 协议或者使用 SSH 传输协议,比如 user@server:path/to/repo.git

记录每次更新到仓库

工作目录中的文件状态分别是 : 已跟踪和未跟踪。已跟踪又分:未修改、已修改和已放入暂存区。工作目录中出了已跟踪的文件之外都是未跟踪的。

Git 文件的生命周期如下:

Git 文件的状态变化

检查文件的状态

使用 git status 来查看,

1
2
3
git status
On branch master
nothing to commit, working directory clean

上述信息表明:当前分支是 master , 工作目录比较干净没有任何提交。

如果我们新建一个 README.txt 文件,通过 git status 命令来查看显示如下:

1
2
3
4
5
6
7
8
9
$ echo 'readme' > README.txt
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.txt
nothing added to commit but untracked files present (use "git add" to track)

此时 新建的 README.txt 文件出现在 Untracked files 下面,说明 README.txt 未纳入 Git 的跟踪范围。 Git 会根据当前文件的状态给出上面的友好提示,方便我们进一步操作。

跟踪新文件

命令是 git add , 如果要跟踪 README.txt 文件,执行:

1
git add README.txt

此时运行 git status 命令,如下:

1
2
3
4
5
6
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README.txt

会看到 README.txt 文件已被跟踪,并处于 stage (暂存) 状态。git add 命令使用文件或目录的路径作为参数;如果参数是目录的路径,该命令将递归地跟踪该目录下的所有文件。 如果要从缓存区撤销文件需要执行git reset HEAD <file>...

暂存已修改文件

如果你要修改工作目录中的 CONTRIBUTING.md 文件,修改之后运行 git status 命令,显示如下:

1
2
3
4
5
6
7
8
9
10
11
12
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md

文件 CONTRIBUTING.md 出现在 Changes not staged for commit 这行下面,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。要暂存这次更新,需要执行 git add 命令。

  • git add 命令有很多的作用,如下:
    • 跟踪新文件
    • 把已跟踪的新文件放到暂存起
    • 把合并时的冲突文件标记为已解决状态。

我们可以把它理解为“添加内容到下一次提交中”。

执行 git add 命令将 CONTRIBUTING.md 放到暂存区,再执行一遍 git status 显示如下:

1
2
3
4
5
6
7
8
git add CONTRIBUTING.md
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
modified: CONTRIBUTING.md

此时, CONTRIBUTING.md 文件已经被添加到暂存区。当我们再次对 CONTRIBUTING.md 进行修改时,执行一遍 git status 看看,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
modified: CONTRIBUTING.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md

此时 CONTRIBUTING.md 同时出现在了暂存区和工作区, Git 暂存区暂存的是你执行 git add 时 文件的快照,如果你执行 git commit 命令,你会把存在暂存区的文件提上去,但是你本次修改并不会提到本地版本库中。如果把本次版本入库,需要执行 git add 命令,把最新的文件放到 暂存区中。

  • 状态简揽 git status --s / git status --short

忽略文件

Git 会自动为我们创建 .gitignore 文件,在这个文件中可以列出要忽略的文件。规则如下:

文件 .gitignore 的格式规范如下:

  • 所有空行或者以 开头的行都会被 Git 忽略。
  • 可以使用标准的 glob 模式匹配。
  • 匹配模式可以以(/)开头防止递归。
  • 匹配模式可以以(/)结尾指定目录。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。

Github .gitignore 文件忽略库

文件差异

要查看已暂存和未暂存的差异,使用 git diff 命令,该命令比较的是工作区文件和暂存区文件的差异。

如果要查看已暂存的将要添加到下次提交的内容,可以使用 git diff --cached 命令或者 git diff --staged 命令。

我们也可以指定 第三方工具帮助我们分析文件的差异,需要配置 git difftool 命令。

文件提交

提交时记录的是放在暂存区域的快照。 任何还未暂存的仍然保持已修改状态,可以在下次提交时纳入版本管理。 每一次运行提交操作,都是对你项目作一次快照,以后可以回到这个状态,或者进行比较。命令如下:

git commit

git commit -m "...."

  • 跳过使用暂存区 git commit -a

移除文件

Git 中移除某个文件,实质上是从暂存区移除,然后执行提交。使用 git rm 命令。 如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f

如果我们想把 git 仓库中的文件删除但想保留在本地,我们可以执行 git rm --cached <file>… 命令。

移动文件

1
git mv file_old file-new

查看提交历史

查看提交历史

使用 git log 来开始查看提交历史,该命令有许多选项可以帮助你搜寻你所要找的提交,介绍一些比较常用的。

git log -p -2 用来显示最近两次提交的内容差异

git log --stat 查看每次提交的简略的统计信息

git log --pretty 指定使用不同于默认格式的方式展示提交历史。很多子选项也是很有用的,

  • oneline 将每个提交显示在一行

    1
    git log --pretty=oneline
  • format 定制要显示的记录格式

    1
    git log --pretty=format:"%h - %an, %ar : %s"

撤销操作

遗漏文件没有提交

执行 git commit --amend 尝试重新提交,会覆盖一切上次提交, git 记录里只会有一次提交。

取消暂存区文件

执行 git reset HEAD <file>… 可以对文件取消暂存

撤销对文件的修改

执行 git checkout file 可以撤销你对文件做的所有修改,它的原理是拷贝了另一个文件来覆盖它。是一个很危险的命令。

远程仓库

查看远程仓库

执行 git remote 命令,会列车远程服务器的简写。 origin 是远程仓库服务器的默认名字。

git remote -v 会显示读写远程仓库的简写与对应的 Url

1
2
3
git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)

添加远程仓库

运行 git remote add <shortname> <url> 命令,会添加一个新的 Git 仓库,使用 pb 来代替 Url。

1
2
3
4
5
6
7
8
git remote
origin
git remote add pb https://github.com/paulboone/ticgit
git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb https://github.com/paulboone/ticgit (fetch)
pb https://github.com/paulboone/ticgit (push)

抓取与拉取远程仓库

  • git fetch [remote-name] 该命令会将远程仓库的数据拉取到本地仓库, 但它并不会自动合并或者修改你当前的目录,你必须手动完成合并工作。
  • git pull [remote_name] 该命令会自动抓取然后合并远程分支到当前分支。

推送到远程仓库

git push [remote-name] [brach-master]

查看远程仓库信息

git remote show [remote-name]

移除和重命名远程仓库

git remote rename old new 修改远程仓库的名字

git remote rm old 移除远程仓库

打标签

git tag 会列出已有的标签

git tag -l 'v1.8.5*' 使用特定模式查找标签

创建标签

  • 附注标签 git tag -a [tag_info]

    1
    git tag -a v1.4 -m 'my version 1.4'

    git show v1.4 可以看到标签信息和对应的提交信息

  • 轻量标签

    git tag [info]

  • 后期打标签

    git tag -a v1.2 [指定提交校验和]

共享标签

git push origin [tagname] 推送标签到共享服务器。

git push origin --tags 一次将所有不在远程仓库的标签传送到服务器。

检出标签

git checkout -b [branchname] [tagname] 在特定标签创建一个新的分支。

Git 别名

通过 git config 文件来为每个命令设置别名,如下:

1
2
3
4
5
6
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'