GIT原理
git结构:
- 众所周知,本地git分为工作区(写代码的地方)、缓存区(后面再说)、本地仓库(存放各个版本的地方)。git中每条分支都有自己的缓存区和本地仓库,由git中的head指针来指向当前操作的是哪个分支的哪个版本。并且每个分支都有两种状态:常态和变态。处于常态的br对工作区作出改动后会变成变态;处于变态的分支在add+commit之后变为常态。
- 云端git可视为只有云端仓库。
git运行:
在init出一个本地仓库后,系统会先给我们一个虚拟分支:master,其有以下特点:
- master不会被head锁指向,因此用git branch也查看不到它
- 由于master没有任何资源且不被head指向,所以其不能创建其他分支
- 该分支在commit到自己的本地仓库后会变成真实分支,被head所指向,此时1、2两点失效
对于一个真实分支来说,其可能有一下运行情况:
- br1常态时切换到其他分支br2:可成功切换,即让head指向br2
- br1变态时切换到其他分支br2:不可成功切换(除情况4以外),br1必须先变为常态
- br1常态时创建新分支br2:可成功创建,br1对应本地库的最新版本会克隆给br2
- br1变态时创建新分支br2:可成功创建,且此时head会同时指向br1和br2,两者之一发生任何变化对方也会跟着变(直到一方进入常态为止),且变态下双方可互相切换
- br1常态时合并(Push)到其他仓库:可成功Push
- br1变态时合并(Push)到其他仓库:可成功Push,但没commit的部分不会Push到其他仓库
- br1常态时被合并(Pull、Merge):可成功合并
- br1变态时被合并(Pull、Merge):可成功合并
git合并:
合并的概念:
- git中的合并指的是其他分支要merge(本地合并)或pull、push(远程合并)到本分支。本分支内的commit不算是合并,会直接覆盖本地库的文件不会产生冲突问题。
冲突问题:
-
我们都知道git中,除最开始的根分支外其他分支都只能在分支的基础上被创建,每个分支被创建(git branch、git clone)时,都会继承其父分支的本地库的最新版本。于此同时,git还会问这些分支的每个版本创建一颗版本树,其中每个分支的每个版本都是一个节点,如图所示:
-
这也是为什么刚init出来的分支不能创建新分支,因为它连自己的版本都没有,自己都不是树种的节点,怎么创建子节点。
-
在进行合并时,两个版本节点会拿自己的文件与最近的共同父节点对比,比完之后文件被分为两类:第一类为文件自上最近父节点来改动过(改动的唯一方式即commit);第二类为没改动过。如此一来,合并时就只有三种情况:
- 变过的文件f1—合并到—>没变过的文件f2:f1会直接覆盖f2
- 没变过的文件f1—合并到—>没变过的文件f2:不做处理
- 变过的文件f1—合并到—>变过的文件f2:管理员协商由谁覆盖
注意:
- 若没有找到共同父节点,则命令会报错!比如你的本地分支是git
init出来的,则该分支与云端的分支没有半毛钱关系,其不能对云端进行push、pull。
个人常用命令
- git init //创建本地仓库 并默认创建一条master分支
- git clone [url] //克隆远程仓库中的主分支
- git clone -b [remote branch name] [url] //克隆远程仓库指定名称的分支
- git status //查看工作区和暂存区情况
- git add .
- git commit -m [commit message]
- git push [url] [local branch name1:remote branch name2] //将本地名为name1的分支同步给云端名为name2的分支(云端没有则新建再同步)
- git remote add [remote branch name] [url] //为远程仓库url取别名
- git branch //查看本地分支
- git remote //查看云端分支
- git branch [new local branch name] //在本地新建一个名为name 的分支
- git switch [local branch name] //切换到本地名为name的分支
- git merge [local branch name] //将本地名为name的分支合并到当前分支
- git pull [url] [remote branch name] //将云端名为name的分支合并到当前分支
- git reflog //简要日志
- git log //详细日志
- git reset --hard [version num] //切换到版本号(通过log查看)所指定的版本
涉及Linux命令:
- vim [file name] 编辑文件(esc进入命令模式,i进入插入模式,:wq保存退出,:q不保存退出)
- cat [file name]查看文件