廖雪峰Git教程学习
之前简单学习了Git
,因此现在进行系统的学习并完成笔记。
笔记的顺序按照个人习惯进行了调整,并非完全按照廖雪峰老师的顺序。
创建版本库
-
git init
初始化仓库 -
git add
将工作区修改文件添加到暂存区stage
-
git commit -m 'xxx'
将暂存区stage
文件添加到本地版本库
时光机穿梭
基本命令
-
git status
查看仓库状态输入上述命令行后出现
Changes not staged for commit:
表示工作区的内容没有存储到暂存区stage
Changes to be committed:
表示暂存区的内容没有提交到版本库Untracked files:
工作区新增加的文件
-
git diff filename
查看文件已经修改的内容(工作区未提交内容和最近一次已提交内容的比较)
工作区和暂存区
-
不
add
到暂存区的内容是不会被commit
到版本库的。换句话说,
commit
只会将暂存区的内容提交到版本库。
撤销修改(工作区和暂存区)
-
git checkout -- filename
直接丢弃工作区的修改。后面–很重要,没有就变成了创建分支把
filename
文件在工作区的修改全部撤销,这里有两种情况:- 文件没有添加到暂存区,那么撤销修改就会和版本库一模一样
- 文件已经添加到暂存区后又做了修改,那么撤销修改就会变成暂存区之前的内容。注意,此时暂存区的内容依旧存在,没有发生改变。
总结,就让这个文件回到最近一次
git commit
或git add
时的状态。 -
git reset HEAD filename
直接丢弃暂存区修改的内容。相当于没`add`
总结:不同场景的撤销修改
-
场景1:直接丢弃工作区的修改,
git checkout -- filename
-
场景2:直接丢弃暂存区的修改:
git reset HEAD filename
git checkout -- filename
-
场景3:提交到暂存区,又修改了工作区内容,想要丢弃暂存区修改:
git checkout -- filename
git reset HEAD filename
git checkout -- filename
-
场景4:提交了不合适内容到版本库,见下一节
前提是没有推送到远程仓库git reset --hard xxx
版本回退(commit回退)
-
git log
查看已提交commit
的记录(已经回退的不显示),回退到历史哪个版本。 -
git reflog
查看全部提交历史(只要有commit
记录的全部显示),回到未来的某个版本。 -
版本回退
回退如果工作区和暂存区修改内容为空,回退后工作区的内容就是回退到的版本。
git reset --hard HEAD^
回退到上一个版本^
代表是上一个,几个箭头代表之前几个。~xxx
代表xxx
个之前
git reset --hard 提交id
回退/跳转到指定版本
删除文件
如果删除错误,可以使用git checkout -- filename
撤销删除
- 场景1:程序员手动删除文件 工作区
rm filename
或使用文件管理器手动删除git add filename
删除添加到暂存区git commit -m 'xxx'
- 结果:删除了工作区和版本库的文件。
- 场景2:删除工作区文件并同时放入暂存区 工作区
git rm filename
git commit -m 'xxx'
- 结果: 删除了工作区和版本库的文件
上述两个场景中,在未
commit
之前可以使用git checkout -- filename
撤销删除工作区文件
- 场景3:删除暂存区文件,但保留工作区的文件,并且将这次删除操作放入暂存区。
git rm --cached filename
git commit -m 'xxx'
将删除操作同步到版本库,版本库会删除这个文件- 结果: 删除了暂存区和版本库的文件,但保留了工作区的文件。
远程仓库
本地仓库和远程库关联
略
从已有远程库克隆
略
分支管理
创建分支
-
git
会将每次提交串成一条时间线,这条时间线就是一个分支。 -
严格来说,
HEAD
指向的是当前分支。 -
相关命令
git branch
查看分支git branch -d xxx
删除分支git checkout -b xxx
创建并切换分支
合并分支merge
merge原理
merge
采用递归三路合并算法对比不同文件之间的行差异。三路合并算法的基本原理是:找到两个merge文件的共同祖先,然后比较三者差异,最后将这些差异合并到一个新的提交中。
具体来说:
- 假如 A、C 内容一致,说明这是在 F 中更改的内容,需要保留该更改;
- A、F 内容一致同上;
- 假如 C、F 内容一致,说明 C 和 F 都相对于 A 做了同样的更改,同样需要保留。
- 如果 A、C、F 的内容都一致,说明什么都没有发生;
- 如果该行在 A、C、F 的内容都不一致,说明发生了冲突,需要我们手动合并选择需要保留的内容。
git merge --no-ff 待合并分支
,建议使用这个命令合并分支让合并路径更加简洁。
多人协作
fetch
-
作用
git fetch
是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。取回更新后,会返回一个
FETCH_HEAD
,指的是某个branch在服务器上的最新状态,我们可以在本地通过它查看刚取回的更新信息: -
命令
` git fetch <远程主机名> <分支名> `分支名>远程主机名>
git fetch origin master
git merge FETCH_HEAD
将拉取下来的最新内容合并到当前所在的分支中
pull
-
作用:将远程主机的最新内容拉下来后直接合并,即:
git pull = git fetch + git merge
,这样可能会产生冲突,需要手动解决。git pull # 等价于 git fetch origin master # 从远程主机的master分支拉取最新内容 git merge FETCH_HEAD # 将拉取下来的最新内容合并到当前所在的分支中
-
语法:
git pull
默认获取远程master
分支和当前分支合并git pull <远程主机名> <远程分支名>:<本地分支名>
将远程分支和本地分支合并git pull origin <远程分支名>
如果远程分支是与当前分支合并,冒号后可以省略
为什么每次
push
前都要pul
一下?
可以在本地提前解决可能出现的冲突,从而减少远端接受push出现冲突的概率。
其实如果有冲突,
push
操作是过不去的,会强制先pull
先在本地操作。
参考文章