Git 基础(1)
Git 基础(1)
1、特点
-
直接记录快照,而非差异比较
-
近乎所有操作都是本地执行
-
Git 保证完整性( Git 中所有的数据在存储前都计算校验和,然后以校验和来引用 )
-
Git 一般只添加数据(安心)
2、三种状态
已提交(committed)、已修改(modified) 和 已暂存(staged)
- 已修改表示修改了文件,但还没保存到数据库中。
- 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
- 已提交表示数据已经安全地保存在本地数据库中。
3、初次运行 Git 前的配置
安装完 Git 之后,要做的第一件事就是设置你的用户名和邮件地址。
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
# 检查配置信息
$ git config --list
user.name=John Doe
user.email=johndoe@example.com
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
...
# 通过key来查询
git config user.name
# 获取某个命令的帮助
$ git add -h
usage: git add [<options>] [--] <pathspec>...
-n, --dry-run dry run
-v, --verbose be verbose
-i, --interactive interactive picking
-p, --patch select hunks interactively
-e, --edit edit current diff and apply
-f, --force allow adding otherwise ignored files
-u, --update update tracked files
--renormalize renormalize EOL of tracked files (implies -u)
-N, --intent-to-add record only the fact that the path will be added later
-A, --all add changes from all tracked and untracked files
--ignore-removal ignore paths removed in the working tree (same as --no-all)
--refresh don't add, only refresh the index
--ignore-errors just skip files which cannot be added because of errors
--ignore-missing check if - even missing - files are ignored in dry run
--chmod (+|-)x override the executable bit of the listed files
4、获取 Git 仓库
4.1、在已存在目录中初始化仓库
$ git init
该命令将创建一个名为 .git
的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。 但是,在这个时候,我们仅仅是做了一个初始化的操作,你的项目里的文件还没有被跟踪。
如果在一个已存在文件的文件夹(而非空文件夹)中进行版本控制,你应该开始追踪这些文件并进行初始提交。 可以通过 git add
命令来指定所需的文件来进行追踪,然后执行 git commit
:
$ git add *.c
$ git add LICENSE
$ git commit -m 'initial project version'
现在,你已经得到了一个存在被追踪文件与初始提交的 Git 仓库。
4.2、克隆现有的仓库
$ git clone https://github.com/libgit2/libgit2
如果你想在克隆远程仓库的时候,自定义本地仓库的名字,你可以通过额外的参数指定新的目录名:
$ git clone https://github.com/libgit2/libgit2 mylibgit
5、记录每次更新到仓库
你工作目录下的每一个文件都不外乎这两种状态:已跟踪 或 未跟踪
# 查看跟踪状态
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
# 跟踪新文件
$ git add README
# 状态简览 新添加的未跟踪文件前面有 ?? 标记,新添加到暂存区中的文件前面有 A 标记,修改过的文件前面有 M 标记
$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt
5.1、忽略文件
文件 .gitignore
的格式规范如下:
- 所有空行或者以
#
开头的行都会被 Git 忽略。 - 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。
- 匹配模式可以以(
/
)开头防止递归。 - 匹配模式可以以(
/
)结尾指定目录。 - 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(
!
)取反。
# 忽略所有的 .a 文件
*.a
# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a
# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO
# 忽略任何目录下名为 build 的文件夹
build/
# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt
# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf
5.2、查看已暂存和未暂存的修改
如果 git status
命令的输出对于你来说过于简略,而你想知道具体修改了什么地方,可以用 git diff
命令。
# 查看尚未暂存的文件更新了哪些部分(工作区 diff 暂存区)
git diff
# 要查看已暂存的将要添加到下次提交里的内容(暂存区 diff 上次提交)
git diff --stage
5.3、提交更新
# 带信息提交
$ git commit -m "Story 182: Fix benchmarks for speed"
# 跳过暂存区提交已跟踪(纳入版本管理的文件):给 git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤:
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
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
no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -a -m 'added new benchmarks'
[master 83e38c7] added new benchmarks
1 file changed, 5 insertions(+), 0 deletions(-)
5.4、移除文件
# 彻底删除文件,并从版本管理中移除
rm README
git rm README
# 移除已经放到暂存区的README文件,但保留工作区README文件(场景:当你忘记添加 .gitignore 文件,不小心把一个很大的日志文件或一堆 .a 这样的编译生成文件添加到暂存区时)
git rm --cached README
# git rm 命令后面可以列出文件或者目录的名字,也可以使用 glob 模式。比如:
git rm log/\*.log
# 注意到星号 * 之前的反斜杠 \, 因为 Git 有它自己的文件模式扩展匹配方式,所以我们不用 shell 来帮忙展开。 此命令删除 log/ 目录下扩展名为 .log 的所有文件。 类似的比如:
$ git rm \*~
#该命令会删除所有名字以 ~ 结尾的文件
5.4、移动文件
不像其它的 VCS 系统,Git 并不显式跟踪文件移动操作。 如果在 Git 中重命名了某个文件,仓库中存储的元数据并不会体现出这是一次改名操作。 不过 Git 非常聪明,它会推断出究竟发生了什么,至于具体是如何做到的,我们稍后再谈。
既然如此,当你看到 Git 的 mv
命令时一定会困惑不已。 要在 Git 中对文件改名,可以这么做:
$ git mv file_from file_to
# 当你再次查看状态时:
$ git mv README.md README
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README
其实,运行 git mv
就相当于运行了下面三条命令:
$ mv README.md README
$ git rm README.md
$ git add README
6 、查看提交历史
6.1、基础
$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : changed the version number
085bb3b - Scott Chacon, 6 years ago : removed unnecessary test
a11bef0 - Scott Chacon, 6 years ago : first commit
主要选项:
- -p:
-p
或--patch
,它会显示每次提交所引入的差异(按 补丁 的格式输出)。 你也可以限制显示的日志条目数量,例如使用-2
选项来只显示最近的两次提交 - --stat: 你想看到每次提交的简略统计信息,可以使用
--stat
选项 - --pretty: 这个选项可以使用不同于默认格式的方式展示提交历史。 这个选项有一些内建的子选项供你使用。 比如
oneline
会将每个提交放在一行显示,在浏览大量的提交时非常有用。 另外还有short
,full
和fuller
选项,它们展示信息的格式基本一致,但是详尽程度不一 --since
和--until
: 按照时间作限制,例如:$ git log --since=2.weeks
选项 | 说明 |
---|---|
%H |
提交的完整哈希值 |
%h |
提交的简写哈希值 |
%T |
树的完整哈希值 |
%t |
树的简写哈希值 |
%P |
父提交的完整哈希值 |
%p |
父提交的简写哈希值 |
%an |
作者名字 |
%ae |
作者的电子邮件地址 |
%ad |
作者修订日期(可以用 --date=选项 来定制格式) |
%ar |
作者修订日期,按多久以前的方式显示 |
%cn |
提交者的名字 |
%ce |
提交者的电子邮件地址 |
%cd |
提交日期 |
%cr |
提交日期(距今多长时间) |
%s |
提交说明 |
你一定奇怪 作者 和 提交者 之间究竟有何差别, 其实作者指的是实际作出修改的人,提交者指的是最后将此工作成果提交到仓库的人。 所以,当你为某个项目发布补丁,然后某个核心成员将你的补丁并入项目时,你就是作者,而那个核心成员就是提交者。