一、工作原理
参考:
Git - Git 基础git-scm.com- 传统版本控制系统工作原理:以文件变更列表的方式存储信息,将它们保存的信息看作是一组基本文件和每个文件随时间逐步累积的
差异
。
- Git版本控制原理:把数据看作是对小型文件系统的一组
快照
,每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索,为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个快照流。
二、生命周期
2.1 Local(本地仓库)
Working directory
(Git 的工作目录): 在工作目录中修改某些文件。Staging area
(暂存区域): 对修改后的文件进行快照,然后保存到暂存区域。Git directory(repository)
(本地仓库): 提交更新,将保存在暂存区域的文件快照永久转储到 Git 目录中。
2.2 remote(远程仓库)
// =====================================
// 1 在工作目录中初始化新仓库
// =====================================
// 说明:初始化后,在当前目录下会出现一个名为 .git 的目录,所有 Git 需要的数据和资源都存放在这个目录中
$ git init
// 添加文件
$ touch README.md
// 对文件进行跟踪,保存到暂存区域
$ git add README.md
// 将暂存区域文件快照永久转储到 Git 目录中
$ git commit -m 'initial project version'
// =====================================
// 2 从现有仓库克隆
// =====================================
// [clone] 本地没有repository时,将远程repository整个下载过来
$ git clone git://github.com/schacon/grit.git
// [checkout] 本地有repository时,将远程新的 commit 下载过来,并与本地代码merge
$ git checkout -b iss01 // ==> 1. git branch iss01 2.git checkout iss01
// [pull] 拉取最新代码
$ git pull
三、分支创建
参考:
Git - 何谓分支git-scm.com实际场景1:
- 项目中,开发新功能 [
新建 iss01 分支
] - 开发过程中,突然遇到线上紧急 bug,需要优先修复 [
新建 bug01分支
] - bug 修复后,需要切换回 mater,然后合并 bug01 分支
- 此时的bug01分支,可以删掉
- 继续在 iss01 分支上进行功能开发
- 功能开发完成后,切换到master分支,合并iss01分支
// 1.新建分支
$ git branch iss01
// 2.切换分支
$ git checkout iss01
// 合并步骤1,步骤2,新建并切换分支
// $ git checkout -b iss01
// 3.在工作区添加文件
$ touch a.md b.md c.md
// 4.add 从工作区添加到暂存区
// 暂存操作会对每一个文件计算校验和(SHA-1 哈希字串)
$ git add a.md b.md c.md
// 5.从暂存区保存到本地仓库
// 把当前版本的文件快照保存到 Git 仓库中
$ git commit -m 'add a.md b.md c.md'
// 6.此时遇到 紧急bug需要修复,需要新建分支进行修复 index.html
$ git checkout master // 先切换至master
$ git checkout -b bug01 // 新建bug01分支进行修复
$ vim index.html // 编辑文件 index.html 修复bug
$ git commit -m 'bug fixed, in index.html' // 保存到本地仓库
$ git checkout master // 再次切换到master
// 7.合并分支
$ git merge bug01
// 8.删除分支 (bug修复后,分支合并,然后可以删除 bug01分支 )
$ git branch -d bug01
// 9.切换回 iss01 分支
$ git checkout iss01
// 10.iss01开发完成后,进行代码合并
$ git checkout master // 切换回master
$ git merge iss01 // 代码合并
// 11.如果存在冲突
$ git status // 查看是否有冲突
// 如果有冲突,可以看到 unmerged 文件,然后手动解决冲突
$ git add // 解决完冲突之后,将把它们标记为已解决状态
$ git status // 再次查看冲突是否解决
$ git commit -m 'fixed unmerged file' // 提交
四、提交本地分支到远程
参考:
Git - 远程分支git-scm.com实际场景2:
- 在本地创建分支
branch_test
- 提交本地分支到远程
- 删除本地分支
- 删除远程分支
// 1.创建本地分支
$ git checkout -b branch_test
// 或拉取远程分支到本地
$ git checkout -b branch_test origin/branch_test
// 2.提交本地分支到远程
$ git push origin branch_test:branch_test
// 3.删除本地分支
$ git checkout master // 需要先切换到master分支,才能执行删除操作
$ git branch -a // 查看所有分支 local/remote
$ git branch -d branch_test // 删除本地分支
// 4.删除远程分支
$ git push origin --delete branch_test
五、打标签
参考:Git - 打标签
// 1.打标签
$ git tag v0.1 // 轻量级标签
$ git tag -a v0.3 -m 'tag message info' // 含附注标签 -a (annotated) -m (message)
// 2.查看标签
$ git tag // 查看所有标签
$ git tag -l 'v0.*' // 查看匹配标签
// 3.查看版本信息,以及提交对象
$ git show // 所有
$ git show v0.1 // 指定标签
// 4.后期加注标签
$ git log --pretty=oneline // 查看提交信息
// 15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
// a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
$ git tag -a v0.2 a6b4c97 // 给 a6b4c97 补打标签
// 5.签署标签 -a 换为 -s (signed)
$ git tag -s v0.2 -m 'my signed 0.2 tag' // 如果你有自己的私钥,还可以用 GPG 来签署标签
$ git show v0.2 // 会看到对应的 GPG 签名也附在其内
// 6.验证标签 -v (verify)
$ git tag -v v0.2
// 7.删除tag -d (delete)
$ git tag -d v0.1
六、重要概念
6.1 暂存(git stash)
经常有这样的事情发生,当你正在进行项目中某一部分的工作,里面的东西处于一个比较杂乱的状态,而你想转到其他分支上进行一些工作。问题是,你不想提交进行了一半的工作,否则以后你无法回到这个工作点。解决这个问题的办法就是git stash命令。
Git - 储藏(Stashing)git-scm.com// 1.提交(正常情况下想要切换分支的时候,我们需要先提交)
$ git commit -m 'message'
// 2.储藏(但是如果此时我们并不想立即 commit 提交,需要先暂存)
// - 会往堆栈推送一个新的储藏,你的变更都保存在栈上
$ git stash
$ git stash list // 要查看现有的储藏
// stash@{0}: WIP on master: 049d078 added the index file
// stash@{1}: WIP on master: c264051 Revert "added file_size"
// 从堆栈中取出 最近的stash,但不会删除该stash
$ git stash apply // 默认使用 stash@{0}
$ git stash apply stash@{1} // 选择使用更早的 stash@{2}
$ git stash drop stash@{0} // 移除存储
// 3.Do the merge, and then pull the stash:
// 从堆栈中取出 最近的stash,并删除该stash
$ git stash pop
// 4.放弃本地更改
$ git reset --hard
$ git checkout -t -f remote/branch
$ git checkout filename // 放弃特定文件的本地更改
6.2 重置(git reset)
Git - 重置揭密git-scm.com- HEAD:你的上一次提交
HEAD快照实际的目录列表,以及其中每个文件的 SHA-1 校验和
$ git cat-file -p HEAD
tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf
author Scott Chacon 1301511835 -0700
committer Scott Chacon 1301511835 -0700
initial commit
$ git ls-tree -r HEAD
100644 blob a906cb2a4a904a152... README
100644 blob 8f94139338f9404f2... Rakefile
040000 tree 99f1a6d12cb4b6f19... lib
- Index (索引):预期的下一次提交
ls-files 这个幕后的命令,它会显示出索引当前的样子
$ git ls-files -s
100644 a906cb2a4a904a152e80877d4088654daad0c859 0 README
100644 8f94139338f9404f26296befa88755fc2598c289 0 Rakefile
100644 47c6340d6459e05787f644c2447d2595f5d3a54b 0 lib/simplegit.rb
- 工作目录: 你可以把工作目录当做沙盒。在你将修改提交到暂存区并记录到历史之前,可以随意更改。
另外两棵树以一种高效但并不直观的方式,将它们的内容存储在.git
文件夹中。
七、常见问题
Question-1:Commit your changes or stash them before you can merge
// 在合并之前【提交更改】或【存储更改】
// 方法1: 直接提交
$ git commit -am 'xxxx'
// 方法2:先暂存,处理完再继续,处理
$ git stash // 暂存,到栈中
$ git branch -b bug01 // 新建bug 分支
$ git checkout iss01 // 修改完成bug后 切换回当前分支
$ git stash pop // 从栈中取出最近一次暂存,并删除该暂存
// 【开发中经常遇见】
// 另外一种场景是:远程代码库代码做了更改,想先 pull 下来,再继续开发,不想直接 push
$ git stash
$ git pull
$ git stash pop
Question-2:you need to resolve your current index first
// pull 代码的时候:merge 失败,需要先解决冲突
// 方法1:忽略本地更改
$ git checkout master // master 代指当前分支名
// 方法2:回退到merge前
$ git reset --merge