- 首页
- 正文
Pro Git 读书笔记
这是记录Pro Git的读书笔记,有些内容会根据自己的理解加以注释,温故而知新,当中还是可以学到不少知识的
版本控制
版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。
版本控制分为:
集中化的版本控制系统 (CVS、Subversion 以及Perforce等)
分布式版本控制系统(Git、Mercurial、Bazaar 以及 Darcs等)
Git基础
Git有三种状态:
- 已提交(committed):已提交表示数据已经安全的保存在本地数据库中
- 已修改(modified):已修改表示修改了文件,但还没保存到数据库中
- 已暂存(staged):已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中
Git的三个工作区域:
- 工作目录:对项目的某个版本独立提取出来的内容
- 暂存区域:是一个文件,保存了下次将提交的文件列表信息
- Git仓库:Git用来保存项目的元数据和对象数据库的地方
基本的 Git 工作流程如下:
- 在工作目录中修改文件
- 暂存文件,将文件的快照放入暂存区域
- 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录
初次运行 Git 前的配置,有三个地方:
- /etc/gitconfig文件: 包含系统上每一个用户及他们仓库的通用配置
- ~/.gitconfig或 ~/.config/git/config文件:只针对当前用户,可以传递 --global选项让 Git读写此文件
- 当前使用仓库的 Git 目录中的 config文件(就是 .git/config):针对该仓库
注意:每一个级别覆盖上一级别的配置,所以 .git/config的配置变量会覆盖 /etc/gitconfig中的配置变量
获取 Git 仓库
- 在现有目录中初始化仓库
git init
- 克隆现有的仓库
git clone url
记录每次更新到仓库
- 检查当前文件状态
git status
- 跟踪新文件
git add file
- 暂存已修改文件
现在我们来修改一个已被跟踪的文件。 如果你修改了一个名为 CONTRIBUTING.md的已被跟踪的文件,然后运行 git status命令,会看到下面内容:
$ 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 status -s
示例
$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt
说明:新添加的未跟踪文件前面有 ??标记,新添加到暂存区中的文件前面有 A标记,修改过的文件前面有 M标记。 你可能注意到了 M有两个可以出现的位置,出现在右边的 M(红色)表示该文件被修改了但是还没放入暂存区,出现在靠左边的 M(绿色)表示该文件被修改了并放入了暂存区。
忽略文件
在根目录创建 .gitignore 文件
文件 .gitignore的格式规范如下:
- 所有空行或者以 #开头的行都会被 Git 忽略。
- 可以使用标准的 glob 模式匹配。
- 匹配模式可以以(/)开头防止递归。
- 匹配模式可以以(/)结尾指定目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
gitignore 例子:
# 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 add 不会提交的
git commit -m "提交信息"
# 把所有已跟踪的文件进行提交,新的文件如果没有 git add 则不会提交,直接跳过暂存区域
git commit -a -m "提交信息"
移除文件
# 先手工删除文件,再运行这个命令
git rm file
# 把工作区和暂存区的文件删除
git rm -f file
# 把暂存区的文件删除,保留文件在工作区
git rm --cached file
移动文件
# 重命名文件
git mv src_file des_file
git mv 命令相当于:
mv README.md README
git rm README.md
git add README
查看提交历史
git log
# 一个常用的选项是 -p,用来显示每次提交的内容差异。 你也可以加上 -2 来仅显示最近两次提交:
git log -p -2
# 查看提交的简略的统计信息
git log --stat
# 一行显示
git log --pretty=oneline
取消暂存的文件
# 取消暂存的文件
git reset HEAD file
撤消对文件的修改
# 撤消对文件的修改,还原成上次提交时的样子
git checkout -- file
远程仓库的使用
- 查看远程仓库
# 查看远程仓库
git remote
# 查看远程仓库,显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL
git remote -v
- 添加远程仓库
# 添加一个新的远程 Git 仓库,shortname是别名
git remote add <shortname> <url>
示例:
git remote add pb https://github.com/paulboone/ticgit
现在你可以在命令行中使用字符串 pb 来代替整个 URL
git fetch pb
- 从远程仓库中抓取与拉取
# 将数据拉取到你的本地仓库,它并不会自动合并或修改你当前的工作
git fetch [remote-name]
# 自动抓取然后合并远程分支到当前分支
git pull [remote-name]
说明:git fetch 运行之后,可以使用 git diff origin/master 用本地分支跟远程分支做对比,用 git merge origin/master 进行合并,git pull 相当于执行了 git fetch 和 git merge 这两个命令
- 推送到远程仓库
# 推送到远程服务器
git push [remote-name] [branch-name]
# 当你想要将 master 分支推送到 origin 服务器时,远程服务器可以使用 git remote 查看
git push origin master
- 查看远程仓库
# 查看某一个远程仓库的更多信息,这些信息非常有用
git remote show [remote-name]
- 远程仓库的移除与重命名
# 重命名远程仓库名字
git remote rename 已经存在的名字 要修改的名字
# 移除远程仓库名字
git remote rm 名字
打标签
- 列出标签
# 查看标签
git tag
- 创建标签
# 创建附注标签
git tag -a v1.4 -m 'my version 1.4'
# 创建轻量标签
git tag v1.4-lw
Git 分支
Pro Git 分支这块写得挺好的,可以认真去看看
# 分支创建
git branch new_branch
# 分支切换
git checkout branch_name
# 输出你的提交历史、各个分支的指向以及项目的分支分叉情况
git log --oneline --decorate --graph --all
# 建立分支并立即切换到新分支
git checkout -b new_branch
# 删除分支
git branch -d branch_name
# 强制删除分支
git branch -D branch_name
# 把branch_name合并到当前分支
git merge branch_name
# 查看每一个分支的最后一次提交
git branch -v
# 查看哪些分支已经合并到当前分支
git branch --merged
# 查看哪些分支没有合并到当前分支
git branch --no-merged
# 把远程的origin/serverfix分支建立为本地名为serverfix的分支
git checkout -b serverfix origin/serverfix
# 查看设置的所有跟踪分支,如每一个分支正在跟踪哪个远程分支与本地分支是否是领先、落后或是都有
git branch -vv
变基
- 变基的基本操作
之前介绍过,整合分支最容易的方法是 merge 命令。 它会把两个分支的最新快照(C3 和 C4)以及二者最近的共同祖先(C2)进行三方合并,合并的结果是生成一个新的快照(并提交)。
其实,还有一种方法:你可以提取在 C4 中引入的补丁和修改,然后在 C3 的基础上应用一次。 在 Git 中,这种操作就叫做 变基。 你可以使用 rebase 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。
在上面这个例子中,运行:
$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command
它的原理是首先找到这两个分支(即当前分支 experiment、变基操作的目标基底分支 master)的最近共同祖先 C2,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后将当前分支指向目标基底 C3, 最后以此将之前另存为临时文件的修改依序应用。(译注:写明了 commit id,以便理解,下同)
现在回到 master 分支,进行一次快进合并。
$ git checkout master
$ git merge experiment
此时,C4' 指向的快照就和上面使用 merge 命令的例子中 C5 指向的快照一模一样了。 这两种整合方法的最终结果没有任何区别,但是变基使得提交历史更加整洁。 你在查看一个经过变基的分支的历史记录时会发现,尽管实际的开发工作是并行的,但它们看上去就像是串行的一样,提交历史是一条直线没有分叉。
请注意,无论是通过变基,还是通过三方合并,整合的最终结果所指向的快照始终是一样的,只不过提交历史不同罢了。 变基是将一系列提交按照原有次序依次应用到另一分支上,而合并是把最终结果合在一起。
总结
了解git的三种状态:已提交、已修改、已暂存
了解git的三个工作区域:工作目录、暂存区域、Git仓库
我们的任何操作都离不开git的三个工作区域和三种状态
会git的基本操作,比如查看提交记录、当前的状态、删除、撤消、添加等等
会写简单的忽略文件
会使用分支、标签、远程操作
了解变基的使用场景
【上一篇】git常用命令
【下一篇】Flutter的安装和配置