版本控制 Git¶
如何使用 git ?
不知道,只需记住并执行这些 shell 命令就可以进行协同工作。如果你出现错误,保存文件,再删除副本,重新下载就好。
由 C 语言实现
git 底层设计思想¶
- 使用有向无环图来记录
- 使用分支来进行并行工作
folder is called as "tree".
file is called as "blob".
每一个圈对应一个快照,带有提交人信息,如author、message等
快照 snapshow 对应 git 中的术语 commit
type blob = array<byte>
type tree = map<string, tree | blob>
type commit = {
parents : array<commit>
author : string
message : string
snapshot : tree
}
type object = blob | tree | commit
objects = map<string, object>
哈希函数:将一对数据转成一个长字符串
``` python def store(o): id = sha1(o) # SHA-1 哈希 objects[id] = 0
def load(id) return objects[id]
Git 维护一组对象,和一组引用
## git 命令
对对象或引用的操作
```shell
git init # 仓库可视化
ls -a
ls .git # objects 中存对象、refs 中存引用
echo "hello world" > hello.txt
git status
# git 给用户更多选择,可以自由选择想要上传的
git add hello.txt
# 添加到暂存区,相当于告诉 git,这部分内容应该包含在下一次快照中
git commit # 创建快照,在图中生成一个节点
Q:哈希值到底是什么?
A:git cat-file -p 42fb7a2
查看对象的具体内容
Q:为什么要有 git add 和 git commit,而不是直接提交整个快照?
A:因为有的时候我们并不希望在当前快照中保存所有内容
git add 添加到暂存区,帮助我们实现这个功能
git log # 查看提交历史,默认线性排序
git log --all --graph --decorate
git 提供引用,可读的命名
HEAD 指向当前正在查看的提交
# 在历史记录之前移动
git checkout 42fb7a2 # 移动了 HEAD 指针
```bash git diff # 显示当前目录比最近一次commit的区别 git diff 42fb7a2 hello.txt # 执行比较的版本和比较的文件
HEAD 指向的是当前正在查看的提交,注意和当前的文件目录的区别,在没有提交之前,当前的文件目录可以随意修改,而当前正在查看的提交是不会变的。
注意 git 命令和底层数据模型之间的关联
```bash
git branch
git branch cat # 创建一个新分支
git checkout cat # 切换到新分支 HEAD 指向 cat
在开发 cat 时同时开发 dog
git checkout master
git checkout -b dog # 创建和切换
将两个功能合并到一个版本
先合并 cat 分支
git checkout master # 确保在 master 分支
git merge cat # 合并 cat 分支
# 一个比较有趣的事,当一个分支是以 master 分支为基础开发时,要切换到该分支,只需将 HEAD 移向该分支,而不需要创建新的快照 fast forward
再合并 dog 分支
git merge dog # 想要合并 dog 分支
# CONFLICT 合并冲突
git mergetool # git 提供的解决合并冲突的工具
删除冲突标记,修改代码
git merge --continue # 告诉 git 我们解决了冲突,继续合并
git remote # 列出当前仓库的所有远程仓库
git remote add <name> <url> # 默认名字是 origin
git push <remote> <local branch>:<remote branch>
# 简化命令
git branch --set-upstream-to=origin/master # 只需要第一次关联一下远程仓库
git push
默认所有 git 命令都是不联网的,所以需要特殊的命令来与远程仓库通信
git feach # 与远程仓库通信,检索在远程仓库上的更改,并在本地上获取这些更改
git merge # 将本地分支更新到与远程分支指向相同的位置
git pull = git feach + git merge
git clone <url> <folder name> # 获取远程仓库的副本