diff --git a/docs/git/git.md b/docs/git/git.md index 0487443..7a4a556 100644 --- a/docs/git/git.md +++ b/docs/git/git.md @@ -15,6 +15,24 @@ tags: Git 是一个开源的分布式版本控制系统。 +### 什么是版本控制? + +版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 + +### 什么是分布式版本控制系统? + +介绍分布式版本控制系统前,有必要先了解一下传统的集中式版本控制系统。 + +**集中化的版本控制系统**,诸如 CVS,Subversion 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。 + +这么做最显而易见的缺点是中央服务器的单点故障。如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。要是中央服务器的磁盘发生故障,碰巧没做备份,或者备份不够及时,就会有丢失数据的风险。最坏的情况是彻底丢失整个项目的所有历史更改记录。 + +![img](https://git-scm.com/figures/18333fig0102-tn.png) + +**分布式版本控制系统**的客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的提取操作,实际上都是一次对代码仓库的完整备份。 + +![img](https://git-scm.com/figures/18333fig0103-tn.png) + ### 为什么使用 Git? Git 是分布式的。这是 Git 和其它非分布式的版本控制系统,例如 svn,cvs 等,最核心的区别。分布式带来以下好处: @@ -29,33 +47,67 @@ Git 是分布式的。这是 Git 和其它非分布式的版本控制系统, 分布式版本控制系统,每个人电脑中都有完整的版本库,所以某人的机器挂了,并不影响其它人。 -### 原理 +## 原理 -![git-theory.png](http://oyz7npk35.bkt.clouddn.com//image/linux/git/git-theory.png) - -先介绍几个核心概念,介绍概念过程中的命令具体用法会在后面详述,这里暂不做介绍: - -#### 版本库 +### 版本库 当你一个项目到本地或创建一个 git 项目,项目目录下会有一个隐藏的 `.git` 子目录。这个目录是 git 用来跟踪管理版本库的,千万不要手动修改。 -#### 工作区(WORKING) +### 哈希值 -当你 `git clone` 一个项目到本地,本地的项目目录相当于一个工作副本,这就是工作区。 +Git 中所有数据在存储前都计算校验和,然后以校验和来引用。 这意味着不可能在 Git 不知情时更改任何文件内容或目录内容。 这个功能建构在 Git 底层,是构成 Git 哲学不可或缺的部分。 若你在传送过程中丢失信息或损坏文件,Git 就能发现。 -#### 暂存区(STAGING) +Git 用以计算校验和的机制叫做 SHA-1 散列(hash,哈希)。 这是一个由 40 个十六进制字符(0-9 和 a-f)组成字符串,基于 Git 中文件的内容或目录结构计算出来。 SHA-1 哈希看起来是这样: -当你在工作区上执行增删改操作,致使文件状态发生变化,可以通过 `git add` 暂存,存储的区域就是暂存区。 +``` +24b9da6552252987aa493b52f8696cd6d3b00373 +``` -#### 本地仓库(LOCAL) +Git 中使用这种哈希值的情况很多,你将经常看到这种哈希值。 实际上,Git 数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名。 -通过 `git commit` 命令,可以将所有暂存的记录提交到当前分支,这时内容被保存在了本地仓库。此时,工作区相当于是清空了。 +### 文件状态 -#### REMOTE(远程仓库) +在 GIt 中,你的文件可能会处于三种状态之一: -以上的所有版本控制都是在你的本地完成,远程仓库并没有保存你的修改,换句话说,其他人并不知道你的工作。为了让所以人都能看到你的修改,你需要使用 `git push` 将自己的修改推送到远程仓库上。 +- **已修改(modified)** -同理,如果你想知道别人在远程仓库上做了什么修改,你可以使用 `git fetch` 或 `git pull` 同步别人的修改。 + 已修改表示修改了文件,但还没保存到数据库中。 + +- **已暂存(staged)** + + 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。 + +- **已提交(committed)** + + 已提交表示数据已经安全的保存在本地数据库中。  + +### 工作区域 + +与文件状态对应的,不同状态的文件在 Git 中处于不同的工作区域。 + +- **工作区(working)** + + 当你 `git clone` 一个项目到本地,相当于在本地克隆了项目的一个副本。 + + 工作区是对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。 + + +- **暂存区(staging)** + + 暂存区是一个文件,保存了下次将提交的文件列表信息,一般在 Git 仓库目录中。 有时候也被称作`‘索引’',不过一般说法还是叫暂存区。 + + +- **本地仓库(local)** + + 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 本地仓库。 + +- **远程仓库(remote)** + + 以上几个工作区都是在本地。为了让别人可以看到你的修改,你需要将你的更新推送到远程仓库。 + + 同理,如果你想同步别人的修改,你需要从远程仓库拉取更新。 + +![git-theory.png](http://oyz7npk35.bkt.clouddn.com//image/linux/git/git-theory.png) ## 安装 @@ -99,13 +151,15 @@ git version 1.7.1 国外网友制作了一张 Git Cheat Sheet,总结很精炼,各位不妨收藏一下。 +本节选择性介绍 git 中比较常用的命令行场景。 + ![git-cheat-sheet.png](http://oyz7npk35.bkt.clouddn.com//image/linux/git/git-cheat-sheet.png) ### 创建 -##### 复制一个已创建的仓库: +#### 克隆一个已创建的仓库 -``` +```sh # 通过 SSH $ git clone ssh://user@domain.com/repo.git @@ -113,14 +167,71 @@ $ git clone ssh://user@domain.com/repo.git $ git clone http://domain.com/user/repo.git ``` -##### 创建一个新的本地仓库: +#### 创建一个新的本地仓库 -``` +```sh $ git init ``` ### 本地修改 +#### 添加修改到暂存区 + +##### 把指定文件添加到暂存区 + +``` +$ git add xxx +``` + +##### 把当前所有修改添加到暂存区 + +``` +$ git add . +``` + +##### 把所有修改添加到暂存区 + +``` +$ git add -A +``` + +#### 提交修改到本地仓库 + +##### 提交本地的所有修改 + +``` +$ git commit -a +``` + +##### 提交之前已标记的变化 + +``` +$ git commit +``` + +##### 附加消息提交 + +``` +$ git commit -m 'message here' +``` + +#### 储藏 + +我个人更喜欢称之为存草稿。 + +##### 将修改作为当前分支的草稿保存 + +``` +git stash apply +``` + +##### 删除最新一次的 stashed changes: + +``` +git stash drop +``` +### 查看 + ##### 显示工作路径下已修改的文件: ``` @@ -133,82 +244,6 @@ $ git status $ git diff ``` -##### 把当前所有修改添加到下次提交中: - -``` -$ git add . -``` - -##### 把对某个文件的修改添加到下次提交中: - -``` -$ git add -p -``` - -##### 提交本地的所有修改: - -``` -$ git commit -a -``` - -##### 提交之前已标记的变化: - -``` -$ git commit -``` - -##### 附加消息提交: - -``` -$ git commit -m 'message here' -``` - -##### 提交,并将提交时间设置为之前的某个日期: - -``` -git commit --date="`date --date='n day ago'`" -am "Commit Message" -``` - -##### 修改上次提交 - -*请勿修改已发布的提交记录!* - -``` -$ git commit --amend -``` - -##### 修改上次提交的committer date: - -``` -GIT_COMMITTER_DATE="date" git commit --amend -``` - -##### 修改上次提交的author date: - -``` -git commit --amend --date="date" -``` - -##### 把当前分支中未提交的修改移动到其他分支: - -``` -git stash -git checkout branch2 -git stash pop -``` - -##### 将 stashed changes 应用到当前分支: - -``` -git stash apply -``` - -##### 删除最新一次的 stashed changes: - -``` -git stash drop -``` - ### 搜索 ##### 从当前目录的所有文件中查找文本内容: diff --git a/docs/git/git.xmind b/docs/git/git.xmind index 6452f20..009c6b2 100644 Binary files a/docs/git/git.xmind and b/docs/git/git.xmind differ