本文摘抄自《Pro Git》
git特点
git存储数据的方式
git把数据看作是对小型文件系统的一组快照,每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个 快照流。
几乎所有操作都在本地完成
git是分布式软件,在没有网络时,你仍然可以提交代码,此时所有提交保存在本地,当你链接到网络时,即可将你的修改提交的服务器。
因为本地保存了所有记录,所以git在比较做一下操作时速度非常快。
保证完整性
Git 中所有数据在存储前都会基于文件的内容或目录结构使用HSA-1计算校验和,当你的文件改变或者损坏,git都可以检测到
git的三种状态
Git 有三种状态,你的文件可能处于其中之一:已提交(committed)、已修改(modified)和已暂存(staged)。 已提交表示数据已经安全的保存在本地数据库中。 已修改表示修改了文件,但还没保存到数据库中。 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
由此引入 Git 项目的三个工作区域的概念:Git 仓库、工作目录以及暂存区域。
git配置
1. 配置文件
git的配置文件存储在三个地方
- 1 /etc/gitconfig 文件: 包含系统上每一个用户及他们仓库的通用配置。 如果使用带有 --system 选项的 git config 时,它会从此文件读写配置变量
- 2 ~/.gitconfig 或 ~/.config/git/config 文件:只针对当前用户。 可以传递 --global 选项让 Git 读写此文件
- 3 当前使用仓库的 Git 目录中的 config 文件(就是 .git/config):针对该仓库。
配置文件的优先级为 3 > 2 > 1,所以.git/config 的配置变量会覆盖 /etc/gitconfig 中的配置变量
2. 配置用户信息
当安装完 Git 应该做的第一件事就是设置你的用户名称与邮件地址。每一次 Git 的提交都会使用这些信息,并且它会写入到你的每一次提交中,不可更改:
git config --global user.name "x x x"
git config --global user.email "x x x"
当你想要针对当前项目是使用一个用户名时,你可以在当前项目目录下是哟嘎纳不带–global选项的配置
git config user.name "x x x"
git config user.email "x x x"
3. 配置文本编辑器
git有时需要和用户交互,如果你不配置默认文本编辑其,git在交互是会使用默认的文本编辑工具,一般是vi。如果你想使用其他文本编辑器,你可以这样设置
git config --global core.editor emacs
4. 检查配置信息
如果你想检查你的配置信息,你可以使用git config --list
命令
如果你只想看某个配置,你可以使用
git config <key>
命令
例如,你想要看文本编辑器可以这样
5.查看一个命令的帮助信息
如果你想查看revert命令的帮助文档,你可以这样写
方法1: git help revert
方法2: git revert --help
方法3: man git revert
6. 为命令创建别名
如果不想每次都输入完整的 Git 命令,可以通过 git config 文件来为每一个命令设置一个别名。 例如:
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目录,可以把其中的 --global
去掉
现在你可以这样使用他们了
使用git
创建一个git仓库
创建一个仓库有两中方法
方法一
在你要进行管控的文件夹下执行如下命令
git init
方法二
在某个文件夹下执行如下命令
#默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。
$ git clone https://x x x x
如果你想给你下载的文件改个仓库名,你可以这样做
git clone https://xxx yyy
仓库中的文件状态
工作目录中的每个文件都不外呼两中状态:已跟踪或未跟踪.已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区。 工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有放入暂存区。 初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。
编辑过某些文件之后,由于自上次提交后你对它们做了修改,Git 将它们标记为已修改文件。 我们逐步将这些修改过的文件放入暂存区,然后提交所有暂存了的修改,如此反复
有了上面的知识,我们可以使用命令git status
看下一个git仓库中的文件状态
- 新clone一个项目后
这是因为所有文件还尚未更改,另外,当前目录下没有新创建并且未跟着的文件
当你在该目录中新创建一个文件并且修改一个文件后,该命令变为如下输出
你也可以使用功能git status -s
来获取简略的状态提示
跟踪一个文件
跟踪一个新文件可以使用git add
命令
git add filename
跟踪一个文件git add path
递归跟踪该目录下的所有文件
add命令有三个作用
- 跟踪一个文件
- 把一个文件放入暂存区,使其可以在下一次commit时被提交
- 在合并时如果有冲突,可以用来将冲突文件标记为已解决状态
我们现在创建一个文件,将其添加到git中,并修改其中内容,看其状态如何
可以看到该文件同时存在与非暂存区和暂存区,这是因为,我们add 该文件后,再次对该文件进行了更改,如果此时运行commit命令,我们将提交上次add命令时的文件状态,并不会提交当前文件的文件状态,所以,在每次修改完文件后,都要记得add这个文件,将其添加到暂存区
忽略一个文件
当你有有个文件不想加入git中,并且也想在每次git status
时提示该文件为跟踪,那么你可以这样做
- 创建一个.gitignore文件
- 编辑该文件,配置你不想加入git的文件规则
.gittignore格式规范如下
- 所有空行或者以 # 开头的行都会被 Git 忽略。
- 可以使用标准的 glob 模式匹配。
- 匹配模式可以(/)开头防止递归。
- 匹配模式可以(/)结尾指定目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上(!)
看个例子
# 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
查看文件修改的内容
查看一个文件具体修改了什么,可以使用 git diff
命令,该命令将会告诉你当前做的操作还有那些没有暂存.
若要查看已暂存的将要添加到下次提交里的内容,可以用 git diff --cached
命令
提交更新
git使用git commit
命令将暂存区的内容提交到仓库
git commit
不加参数时,git会调用你配置好的便捷器让你输入本次提交的说明.像这样
git commit -v
如果使用加入-v 参数,将会将diff的输出加入提交的内容中git commit -v
git commit -m
使用git commit -m
命令,将提交信息与命令放在同一行,此时将不在调用编辑器
git commit -a
使用git commit -a
命令,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤
git commit --amend
有时候,你想要在上次提交的内容下追加写新内容,但是有不想产生两条提交记录,这时候,你可以使用git commit --amend
命令
删除一个文件
- 将文件从工作目录和仓库中同时删除
git rm fileneme
- 如果在使用git rm前你手动删除了工作目录下的该文件,你在运行git status 命令时,会看到如下输出
下次提交时,你将不能提交,出现这种情况,你可以使用
git rm 文件名
来处理 - 如果你的文件修改过,并且提交到暂存区,此时运行
git rm filename
命令时,会得到如下信息
这是一种安全特性,用于防止误删还没有添加到快照的数据,这样的数据不能被 Git 恢复,你可以安装提示处理该错误 - 如果你只想删除仓库中的文件,但是你又想将本地工作目录中的文件保留,你可以使用如下命令
git rm --cached filename
查看日志
为了方便,我们在我们从github上下载一个开源项目git clone https://github.com/TeamStuQ/skill-map.git
使用命令git log
这个命令会列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明
显示每次提交的差异git log -p
该选项在git log
的基础上增加了文件的改动,还附带了每次 commit 的变化
简略统计提交信息git log --stat
该选项在每次提交的后面列出了所有被修改过的文件、有多少文件被修改了以及被修改过的文件的哪些行被移除或是添加了
指定输出格式git log --pretty
--pretty
可以指定不同的类型,下图是所有的类型
你可以使用git log --pretty=oneline
选项来将每次提交放在一行显示,也可以使用git log --pretty=format
选项来指定自己想要的输出格式.例如 git log --pretty=format:"%h - %an, %ar : %s"
下面是 git log --pretty=format
的常用选项
|选项|说明|
|--|--|
| %H|提交对象(commit)的完整哈希字串
| %h|提交对象的简短哈希字串
| %T|树对象(tree)的完整哈希字串
| %t|树对象的简短哈希字串
| %P|父对象(parent)的完整哈希字串
| %p|父对象的简短哈希字串
| %an|作者(author)的名字
| %ae|作者的电子邮件地址
| %ad|作者修订日期(可以用 --date= 选项定制格式)
| %ar|作者修订日期,按多久以前的方式显示
| %cn|提交者(committer)的名字
| %ce|提交者的电子邮件地址
| %cd|提交日期
| %cr|提交日期,按多久以前的方式显示
| %s|提交说明
展示分支合并历史 git log --graph
搜索关键字 git log --grep
该命令可以搜索提交说明中的关键
搜索关键字 git log -S fun_name
可以列出那些添加或移除了某些字符串的提交。 比如说,你想找出添加或移除了某一个特定函数的引用的提交,你可以这样使用:
git log -Sfunction_name
-
git log 常用选项
项 说明 p 按补丁格式显示每个更新之间的差异。 -stat 显示每次更新的文件修改统计信息。 -shortstat 只显示 --stat 中最后的行数修改添加移除统计。 -name-only 仅在提交信息后显示已修改的文件清单。 -name-status 显示新增、修改、删除的文件清单。 -abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。 -relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。 -graph 显示 ASCII 图形表示的分支合并历史。 -pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。
撤销
撤销上次的日志 git commit --amend
有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend 选项的提交命令尝试重新提交:
git commit --amend
这个命令会将暂存区中的文件提交。 如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令),那么快照会保持不变,而你所修改的只是提交信息
最终你只会有一个提交 - 第二次提交将代替第一次提交的结果。
git reset
关于git reset 请参考《git reset 命令原理》
将暂存的文件撤销 git rest HEAD
当你的文件通过git add
命令已经放到暂存区,但是在下次提交时不想带上该文件,你可以使用 git reset HEAD
命令来将其从暂存区删除.此命令不会修改你当前文件的内容.
git reset --mixed
撤回到上次提交,保留暂存区和工作目录。该命令可以让你重写commit 提交信息但是没有git commit --amend方便
git reset --hard
该命令可以删除暂存区和工作目录中的所有修改。慎用
撤销对文件的修改 git checkout
如果你不想保留当前对文件的修改,想要将它恢复成上次提交后的样子,你可以使用git checkout
git checkout -- [file]
是一个危险的命令,你对该文件做的任何修改都会消失, 你只是拷贝了另一个文件来覆盖它.