本文章最初发布在 XJHui’s Blog,未经允许,任何人禁止转载!
注意:最新修改版本已发布在 这里,点击前往查看!
关于笔记
- 视频地址:Git(中级)教程(12h深入掌握git)(28p)
- 学前基础:- linux
- github
 
- 学后技能:- git底层、高层命令
- git分支、存储、后悔药、标签
- git团队协作、Pull Request
 
版本控制
集中式(svn)
- 原理:服务器存放项目的所有版本,工作时从服务器下载项目最新版本,工作完成后将代码提交到服务器 
- 原理图:   
分布式(git)
- 原理:每台电脑中都存放了项目的所有版本,即使服务器故障也不会影响工作更不会将丢失项目 
- 原理图:   
差异比较
- 存储方式:svn存储版本差异,git存储所有版本   - 注意:git是先压缩后存储,尽管存储占用比svn大,但不会大太多 
- 安全性: - svn:工作时只会下载项目最新版本,如果服务器存储故障,就无法从员工电脑恢复项目所有版本
- git:每位员工电脑上都有项目的所有版本,即使服务器存储故障,任意一位员工都能恢复整个项目
 
- 版本回退速度: - svn:存储的是版本差异,每回退一个版本都需要打一次补丁,导致回退速度慢
- git:存储所有版本,只要找到该版本对应的提交对象,就可直接回退到该版本
 
- 服务器故障时: - svn:新写的代码不满意,不能回退到初始版本
- git:本地操作不受服务器限制,可任意提交、回退
 
- 总结: - svn:存储占用小
- git:安全、高效
 
git
简史
- 创始人:Linus Benedict Torvalds(林纳斯·托瓦兹)   
- git起源:   
安装
- 下载访问: https://xjhui.lanzoux.com/iap7Odtezyf,感谢:蓝奏云   - 注意:如果与您的电脑版本不匹配,请访问:https://git-scm.com/download/win 下载指定版本   
- 安装:一路next   
- 验证安装:桌面右键,出现框选内容代表安装成功   
初始化
- 命令: - 1 - git init # 初始化一个git仓库 
- 案例:在/workspace下初始化一个git仓库 - 文件夹内右键选择 - Git Bash Here:  
- 输入指令: - git init:  - 注意:.git为隐藏文件,若不显示请点击 - 查看-> 勾选- 隐藏的项目  
 
- git文件(.git文件夹内):   - 文件功能: - hooks:存放钩子文件(提交代码前、后要做的事,例如检查代码规范)
- info:说明哪些文件不需要管理
- objects:对象库(类似对象库,存放git对象、树对象、提交对象)
- refs、HEAD:分支相关内容
- description:仓库描述信息
 
git区域
- 三个区域: - 工作区:就是你在电脑里能看到的目录
- 暂存区:一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们有时也把暂存区叫作索引(index)
- 版本库:工作区有一个隐藏目录.git
 - 注意:暂存区是存在于版本库中的,而版本库是存在于工作区的 
- 关系图:   
git底层概念
底层概念代码不需要掌握,但一定得懂
git对象
- 定义:通过 - git hash-object -w命令在objects目录下生成的对象都是git对象
- 生成git对象的方法: - 方法一:将字符串直接写入对象库 - 语法: - 1 - echo 'test content' | git hash-object -w --stdin - 参数功能: - -w:返回hash值并写入对象库,若不添加该参数则只返回hash值
- –stdin:标准输入流读取字符串,不可省略
 - 运行结果:   
- 查看value(字符串)值: - cat命令:  
- git cat-file -p命令:  
- git cat-file -t命令可查看git对象的类型:  
 
 
- 方法二:将文本文件中的字符串写入对象库 - 语法: - 1 - git hash-object -w 文件名 - 参数功能: - -w:返回hash值并写入对象库,若不添加该参数则只返回hash值
- 文件名:包含文本内容的文件,不可省略
 
- 案例1:使用 - git hash-object命令将test.txt文件(v1版本)内容写入到对象库  - 命令: - 1 - git hash-object -w test.txt - 运行结果:   
- 案例2:修改test.txt文件(v2版本),并再次写入对象库   - 命令: - 1 - git hash-object -w test.txt - 运行结果:   - 使用 - find .git/objects/ -type f命令查看所有git对象:  
 
 
- git对象总结:git对象仅能存储文件的内容,对文件名称的存储却无能为力 
树对象
- 定义:解决git对象无法存储文件名称的问题,创建树对象需要先将git对象放入暂存区 
- 将git对象放入暂存区: - 放入前查看缓存区内容: - 1 - git ls-files -s - 运行结果:   
- 将git对象放入暂存区: - 1 - git update-index --add --cacheinfo 100644 a0423896973644771497bdc03eb99d5281615b51 test.txt - 运行结果:   - 参数解释: - –add:文件首次加入暂存区时需要添加该参数
- –cacheinfo:要添加的git对象位于git对象库中,而不是位于当前目录下
- 文件类型:100644( 普通文件)、100755(可执行文件)、120000(符号链接)
 
- 放入后再次查看缓存区内容:   
 
- 生成树对象: - 1 - git write-tree - 运行结果:   - 查看树对象类型:   - 注意:树对象也会被存储到objects目录下:   - git、树对象差异:git对象代表文件的一次次版本,树对象代表项目的一次次版本 
- 树对象的不足: - objects文件中放置了git对象和树对象,很难区分开来
- 有git、树对象但不知道提交人、提交时间、版本差异
 
提交对象
 
- 概念: - 创建树对象后就要创建一个提交对象,用来存储该树对象的具体信息(提交人、时间、注释等信息)
- 每个提交对象分别指向一个树对象和一个父提交对象(第一个提交对象仅指向一个树对象)
 
- 创建提交对象: - 创建第一个提交对象: - 1 - echo '注释' | git commit-tree 树对象 - 运行结果:   - 注意:第一个提交对象不需要指向父提交对象,但其他提交对象必须指向父提交对象 
- 创建其它提交对象: - 1 - echo '注释' | git commit-tree 树对象 -p 父提交对象 - 运行结果:   - 查看提交对象内容:   
 
命令总结
命令中所有对象(git、树、提交对象)都要用对应hash值代替
- git init:初始化git仓库
- 生成git对象:- echo “字符串” | git hash-object -w –stdin:将字符串写入对象库
- git hash-object -w 文件名:将文件内容写入对象库
 
- 生成树对象:- git update-index –add –cacheinfo 文件类型 git对象:将git对象存入暂存区
- git write-tree:生成树对象
 
- 生成提交对象:- echo “注释” | git commit-tree 树对象:生成第一个提交对象
- echo “注释” | git commit-tree 树对象 -p 父提交对象:生成其它提交对象
 
- 查看对象信息:- git cat-file -t 对象:查看对象类型
- git cat-file -p 对象:查看对象内容
- git ls-file -s:查看暂存区内容
- find .git/objects/ -type f:查看对象库中的所有对象
 
git高层命令
最基本流程
- git init:初始化git仓库 
- git add ./:给所有文件生成git对象并添加到暂存区 - 1 
 2- git hash-object -w 文件名 # 等同于该命令被执行n次(n=文件数目) 
 git update-index --add --cacheinfo 文件类型 git对象- 注意:暂存区在版本库中,所以执行git add命令后git对象先进入版本库再进去暂存区 
- git commit -m “提交备注”:生成树对象和提交对象 - 1 
 2- git write-tree # 生成树对象 
 echo "备注" | git commit-tree 树对象 -p 父提交对象 # 生成提交对象
查看文件
- 文件状态:未跟踪、已跟踪(已暂存、已提交、已修改)   
- git status - 查看文件状态(未跟踪、已跟踪(已暂存,已提交,已修改)) - 查看未跟踪文件的状态: - 1 
 2- echo "hello world!" > laofu.txt 
 git status # 查看文件状态- 运行结果:   - 注意:新建的文件为未跟踪状态 
- 查看已跟踪文件状态 - 已暂存: - 1 
 2- git add laofu.txt # 将文件放入暂存区,add后也可跟./或文件夹 
 git status # 查看文件状态- 运行结果:   
- 已提交: - 1 
 2- git commit -m "提交注释" # 将暂存区文件提交到版本库 
 git status # 查看文件状态- 运行结果:   - 注意: - 如果注释内容过多,可以使用git commit 命令在文件中键入注释:   
- 对已跟踪文件,使用git commit命令时添加参数 -a,可跳过git add命令,直接提交到版本库 
 
- 已修改 - 查看已提交的文件修改后状态: - 1 
 2- vim laofu.txt # 修改已提交文件的内容 
 git status # 查看文件状态- 运行结果:   - 注意:虽然改文件未被暂存,但已被跟踪,可以直接使用 git commit -m 命令提交到版本库 
- 查看已暂存的文件修改后的状态: - 1 
 2
 3- git add ./ # 将文件添加到暂存区 
 vim laofu.txt # 修改已暂存文件的内容
 git status # 查看文件状态- 运行结果:   - 注意:已暂存的文件修改后会出现两种状态,必须再次执行git add命令,否则提交的内容还是上次暂存的版本 
 
 
 
- git diff - 批量查看已跟踪文件的状态 - 查看已跟踪的文件中哪些修改需要暂存: - 1 
 2- vim laofu.txt # 修改文件,将其变为未暂存状态 
 git diff # 查看哪些更新需要暂存- 运行结果:   
- 查看已跟踪的文件中哪些暂存需要提交: - 1 
 2- git add ./ # 将文件添加到暂存区 
 git diff --cached # 查看哪些暂存需要提交- 运行结果:   
 
- 查看提交记录 - 详细显示提交记录: - 1 - git log # 查看提交记录(包含提交对象hash值、提交者、时间等) - 运行结果:   - 注意:如果内容过多,可以按上下键翻页查看,按q键退出 
- 单行显示提交记录: - 1 - git log --oneline # 单行显示每条提交记录 - 运行结果:   
- 显示提交记录: - 1 - git log --oneline --decorate --graph --all - 运行结果:   
 
删除文件
- 定义:将某个文件从工作区中删除 
- 案例1:使用rm命令删除laofu.txt文件后再使用 - git status命令查看文件状态- 1 
 2
 3- rm -rf laofu.txt # 删除文件 
 ls # 查看文件目录
 git status # 查看文件状态- 运行结果:   - 1 - git add ./ # 将修改加入暂存区 - 运行结果:   
- 案例2:使用 - git rm命令删除已跟踪的文件,比较与rm的区别  
- 比较 - git rm和- rm:- git rm与- rm -rf+- git add作用相同
修改文件
- 定义:将工作区文件重命名后添加到暂存区 
- 案例1:将laoliu.txt重命名为laoliuliu.txt后将其添加到暂存区,查看文件状态 - 1 
 2
 3
 4- mv laoliu.txt laoliuliu.txt # 文件重命名 
 git status # 查看重命名后的文件状态
 git add ./ # 将改名后的文件添加到暂存区
 git status # 查看重新添加到暂存区后文件的状态- 运行结果:   
- 案例2:使用 - git mv命令重命名已跟踪的文件,比较与mv的区别- 1 
 2- git mv test.txt tests.txt # 文件重命名 
 git status # 查看文件状态- 运行结果:   
- 比较 - git mv和- mv:- git mv与- mv+- git add作用相同
git分支操作
创建分支
- 语法: - 1 
 2- git branch 分支名 # 在当前分支创建分支 
 git branch 分支名 提交对象 # 创建分支并指向某个提交对象
- 案例1:创建一个名为damu的分支 - 1 
 2- git branch damu 
 git log --oneline # 查看当前分支- 运行结果:   - 注意:HEAD所指向的分支就是当前所在分支 
- 案例2:在hash值为e319357的提交对象上创建dev分支 - 1 
 2- git branch dev e319357 # 创建名为dev的分支,指向提交对象e319357 
 git log --oneline # 查看当前分支信息- 运行结果:   - 创建dev分支后,工作区并没有dev分支对应的文件:   - 注意:想要在工作区显示某个分支的文件,就要将当前分支切换到该分支 
切换分支
- 用途:当想给项目添加一个新功能时,就可以新建一个分支 - 对新分支代码满意:将新分支合并到master分支,从而在项目中添加该新功能
- 对新分支代码不满意:回退到master分支
 
- 语法: - 1 
 2- git checkout 分支名 # 切换分支 
 git checkout -b 分支名 # 创建并切换到该分支- 注意: - 每次切换分支之前,都要保证当前分支是干净的(git status看一下,防止分支被污染)
- 切换分支会改变HEAD、暂存区、工作区(版本库内容不会改变,只会无限的增多)
 
- 案例:切换当前分支到dev分支,并显示工作区文件目录 - 1 
 2
 3- git log --oneline # 查看当前分支信息 
 git checkout dev # 切换分支为dev
 ll # 查看工作区文件目录- 运行结果:   - 分支切换到dev后,由于master分支在dev分支的后面,导致使用 - git log命令无法显示:  - 可以使用 - git log --oneline --decorate --graph --all显示完整分支信息:  
删除分支
- 语法: - 1 - git branch -D 分支名 # 删除指定分支 - 注意:若要删除的分支为当前所在分支则必须先切换到其它分支,不可以自己删自己 
- 案例:删除分支dev - 1 
 2- git log --oneline # 查看当前分支 
 git checkout master # 切换分支到master- 运行结果:   - 注意:切换到其它分支前要保证分支干净,但上图未做判断(git status) - 1 
 2- git log --oneline # 再次查看当前分支 
 git branch -D dev # 删除dev分支- 运行结果:   - 注意:其实删除分支的参数是 - -d,- -D是强制删除某个分支
查看分支
- 语法: - 1 
 2
 3- git log --oneline # 查看当前分支 
 git branch # 打印分支列表
 git branch -v # 查看每个分支最后的提交信息(git log也能查看,但不够直观)
- 案例: - 查看当前所在分支: - 1 - git log --oneline # 查看当前分支 - 运行结果:   - 注意:HEAD所指向的分支就是当前所在分支 
- 打印分支列表: - 1 - git branch # 打印分支列表 - 运行结果:   
- 查看每个分支最后的提交信息: - 1 
 2- git branch -v # 显示每个分支最后的提交信息 
 git log --oneline # 显示当前版本信息- 运行结果:   
 
合并分支
- 语法: - 1 - git merge 分支名 # 将当前分支与某分支合并 
- 案例1:将damu分支合并到master分支(快速合并) - 1 
 2
 3- git log --oneline # 查看当前分支 
 git status # 查看文件状态
 git checkout master # 切换到master分支- 运行结果:   - 1 
 2- git merge damu # 将damu分支合并到master分支 
 git log --oneline # 再次查看当前分支- 运行结果:   
- 案例2:模拟并解决合并冲突(典型合并) - 1 
 2
 3
 4
 5- git checkout -b "ct-test" # 创建并切换到新分支 
 ll # 查看文件目录
 vim a.txt # 修改a.txt
 git add ./
 git commit -m "2 commit for a.txt v2 for ct-test"- 运行结果:   - 1 
 2
 3
 4- git status # 切换分支前,确保分支干净 
 git checkout master # 切换分支到master
 vim a.txt # 修改a.txt
 git commit -am "3 commit for a.txt v2 for master"- 运行结果:   - 1 - git merge ct-test # 将ct-test分支合并到master - 运行结果:   - 注意:上图中能看到是a.txt文件冲突 - 1 - vim a.txt # 查看冲突的文件 - 运行结果:   - 1 
 2- git add ./ # 告知git冲突已经解决 
 git commit -m "4 commit for fix ct"- 运行结果:   
其它内容
- 分支模式 - 长期分支:master
- 特性分支:要实现某个功能而开的分支
 
- 分支本质:提交对象   - 注意:每次提交后,分支对应的提交对象都会改变 
- 分支原理: - HEAD:存放其指向的分支名   
- .git/refs/heads:存放该分支对应的提交对象   - 注意:项目中的所有分支都会被存放在.git/refs/heads/master目录下 
 
- 配别名: - 将命令git status配别名为git st: - 1 - git config --global alias.st "status" # 总结配别名的规律 - 运行结果:   - 注意:当双引号中只有一个单词时,可将双引号省略 
- 将命令 git log –oneline –decorate –graph –all 配别名为 git lol: - 1 - git config --global alias.lol "log --oneline --decorate --graph --all" - 运行结果:   
 
git存储
- 应用场景:要切换到其它分支,但当前分支的工作还没有完成,就可以利用git存储 
- 语法: - 1 
 2
 3
 4
 5- git stash list # 查看当前分支下存储栈内容 
 git stash # 保存存储,将当前分支文件存入栈中
 git stash pop # 应用栈顶存储,并将栈顶元素删除
 git stash apply # 仅应用栈顶存储
 git stash drop 元素名称 # 仅删除栈中指定存储- 注意: - 存储后当前分支会变成干净的分支,可以切换到其它分支(其本质还是做了一次提交,只是不计入log)
- 栈中一般只存储一次,否则操作会很复杂
 
- 案例:在damu分支中修改a.txt文件,存储damu分支后切换到master分支,再切换到damu分支并恢复修改 - 1 
 2
 3- git branch # 查看当前所在分支 
 vim a.txt # 修改a.txt内容
 git status # 查看文件状态- 运行结果:   - 注意:当前分支不干净,不能直接切换到master分支 - 1 
 2
 3- git stash # 通过存储当前分支文件,将当前分支变为干净分支 
 git stash list # 查看存储栈
 git status # 查看文件状态- 运行结果:   - 1 
 2
 3
 4- git checkout master # 切换分支到master 
 git checkout damu # 切换分支到damu
 git stash list # 查看当前分支存储内容
 git stash pop # 应用栈顶存储,并删除栈顶内容- 运行结果:   
git后悔药
工作区
撤销修改
- 语法: - 1 - git checkout --文件名 # 撤销修改 
- 案例:master分支下修改a.txt文件后撤销修改 - 1 
 2
 3- git status # 查看文件状态 
 git checkout -- a.txt # 撤销修改
 git status # 再次查看文件状态- 运行结果:   - 注意:git只能撤销已跟踪的文件 
暂存区
撤销暂存
- 语法: - 1 - git restore --staged 文件名 # 撤销暂存 
- 案例:修改a.txt内容并将其添加到暂存区后撤销暂存 - 1 
 2
 3- vim a.txt # 修改文件内容 
 git add ./ # 将文件添加到暂存区
 git status # 查看文件状态- 运行结果:   - 1 
 2- git restore --staged a.txt # 撤销暂存 
 git status # 查看文件状态- 运行结果:   
版本库
撤销提交
- 场景:提交后发现注释错误,需要修改注释 
- 语法: - 1 - git commit --amend # 撤销提交 
- 案例1:提交a.txt后修改注释内容 - 1 
 2- git commit -m "1 commit for a.txt v5" # 提交到版本库 
 git lol # 查看注释- 运行结果:   - 1 
 2- git commit --amend # 撤销提交(修改注释) 
 git lol # 查看注释- 运行结果:   
- 案例2:修改a.txt并将其提交到版本库,修改版本库中a.txt的内容 - 1 
 2
 3
 4- vim a.txt # 修改a.txt文件内容 
 git st # 查看文件状态
 git commit -am "1 commit for a.txt v6 50%" # 提交到版本库
 git lol # 查看版本内容- 运行结果:   - 1 
 2
 3- vim a.txt # 再次修改a.txt文件内容 
 git st # 查看文件状态
 git add ./ # 将修改后的a.txt文件添加到暂存区- 运行结果:   - 注意区分: - 若执行:git commit –amend - 运行结果:   
- 若执行:git commit -m “1 commit for a.txt v6 50%” - 运行结果:   
 - 总结: - 使用 git commit --amend命令会覆盖上次提交
- 使用 git commit -m ""命令提交与上次提交没有关系
 
reset三部曲
reset命令
- 作用:通过移动HEAD来实现版本回退 
- HEAD移动图示:   - 注意:HEAD会带着分支移动,要与checkout(切换分支)区分开 
- 参数: - –soft:只更新版本库内容
- –mixed:更新版本库、暂存区内容
- –hard:更新版本库、暂存区内容
 
–soft
- 语法: - 1 - git reset --soft HEAD~【提交对象】 # 版本回退,并更新版本库内容;HEAD~表示上一次提交,也可使用提交对象 
- 案例:切换file.txt到上一次提交版本   - 1 
 2
 3- git lol # 查看当前版本 
 git reset --soft HEAD~ # 切换版本
 git lol # 再次查看当前版本- 运行结果:   - 1 
 2
 3- cat file.txt # 查看工作区内容 
 git ls-file -s
 git cat-file -p git对象 # 查看暂存区内容- 运行结果:   - 总结:–soft参数只会更新版本库内容,不会更新暂存区、工作区内容 
–mixed
- 语法: - 1 - git reset 【--mixed】 HEAD~【提交对象】 # 版本回退,并更新版本库、暂存区内容 
- 案例:切换file.txt到最后一次提交版本   - 1 
 2- git reflog # 查看第三次提交的提交对象(git reflog能显示全部提交版本) 
 git reset --mixed 提交对象 # 切换到最后一次提交- 运行结果:   - 1 
 2
 3- git lol # 查看版本库变化 
 git ls-files -s
 git cat-file -p git对象# 查看暂存区变化- 运行结果:   - 总结:–mixed参数会更新版本库、暂存区内容,不会更新工作区内容 
–hard
- 语法: - 1 - git reset --hard HEAD~【提交对象】 # 版本回退,并更新版本库、暂存区、工作区内容 
- 案例:切换file.txt到上一次提交版本   - 1 
 2
 3
 4
 5- git reset --hard HEAD~ # 切换到上次提交 
 cat file.txt # 查看工作区变化
 git lol # 查看版本库变化
 git ls-files -s
 git cat-file -p git对象 # 查看暂存区变化运行结果:- 运行结果:   - 总结:–hard参数会更新版本库、暂存区、工作区内容 
- 区分checkout: - checkout只动HEAD,–hard动HEAD而且带着当前分支一起走
- checkout对工作目录是安全的,–hard是强制覆盖工作目录
 
打tag
标签列表
- 标签用途:想要发布项目的1.0.0版本,就可以打一个v1.0.0的标签(版本号) 
- 语法: - 1 
 2- git tag # 列出所有标签 
 git tag -l "1.1.0*" # 列出所有1.1.0以后的版本
创建标签
- 语法: - 1 
 2- git tag v1.0.0 # 创建标签 
 git tag v1.0.0 提交对象 # 给指定提交对象创建标签
- 案例:创建一个v1.0的标签 - 1 
 2- git tag v1.0 # 创建标签 
 git lol # 查看标签- 运行结果:   - 注意:创建新的提交后,tag位置不会随HEAD   
查看标签
- 语法: - 1 - git show v1.0 # 查看指定标签 
- 案例:查看标签v1.0 - 1 - git show v1.0 - 运行结果:   
删除标签
- 语法: - 1 - git tag -d 标签名 # 删除指定标签 
- 案例:给第一次提交打标签v1.0 - 1 
 2
 3
 4- git tag -d v1.0 # 删除原来的v1.0标签 
 git lol # 查看第一次提交的commitHash
 git tag v1.0 提交对象 # 给指定提交对象打v1.0标签
 git lol # 查看版本日志- 运行结果:   
检出标签
- 用途:想查看、修改某个版本的文件内容 
- 语法: - 1 
 2- git checkout "标签号" # 先切换到指定标签 
 git checkout -b "标签号" # 再给当前标签创建分支- 注意:如果仅执行 - git checkout "标签号"这个命令,会导致git处于“头”,“身”分离的状态  
远程仓库
项目经理
- 创建远程仓库 - 登录github,点击右上角“+”,选择New repository:   
- 输入仓库信息:   
- 创建完成:   
 
- 创建工作目录 - 新建空白文件夹:   
- 输入命令,初始化仓库: - 1 - git init # 初始化仓库 - 运行结果:   
 
- 为远程仓库配置别名、用户信息 - 为远程仓库配置别名: - 1 
 2
 3
 4- git remote -v # 显示远程仓库别名和对应url 
 git remote add 别名 url # 添加一个新的远程仓库同时指定一个别名
 git remote rename 别名 新别名 # 重命名远程仓库
 git remote rm 别名 # 删除某个远程仓库- 运行结果:   
- 配置用户信息: - 1 
 2
 3- git config --list # 查看配置信息 
 git config --global user.name "XJHui"
 git config --global user.email "admin@mail.plushine.cn"- 运行结果:   
- 删除配置信息: - 1 
 2- git config --list # 查看配置信息 
 git config --global --unset user.name # 删除配置信息- 运行结果:   
 
- 推送本地项目到远程仓库 - 创建文件,提交到版本库: - 1 
 2
 3- echo "damu.txt v1" > damu.txt 
 git add ./
 git commit -m "1 commit for damu.txt v1 from taobao"- 运行结果:   
- 将版本库内容推送到远程仓库: - 1 
 2- git lol # 查看版本库 
 git push 别名 分支名 # 将版本库内容推送到远程仓库- 运行结果:(下图提到的用户名和密码是github的用户名和密码,非git中所配置的用户信息)   - 推送成功:   
 
- 邀请成员 - 进入项目设置-》Settings-》Manage access-》Invite a collaborator:   
- 输入用户名,搜索成员:   
- 等待成员同意邀请:   - 成员访问邀请链接:   
 
成员操作
- 克隆仓库到本地 - 创建文件夹,克隆项目: - 1 - git clone url # 克隆远程仓库 - 运行结果:   - 注意: - 克隆后会生成一个与远程仓库同名的文件夹存放项目文件
- 成员克隆项目前不需要执行 git init命令
 
- 查看克隆的项目: - 1 
 2
 3- cd git-study # 进入文件夹 
 ll # 查看文件目录
 cat damu.txt # 查看文件内容- 运行结果:   
- 查看项目默认别名: - 1 - git remote -v - 运行结果:   - 注意:克隆下来的仓库别名默认为origin 
 
- 修改文件,推送提交: - 1 
 2
 3
 4- echo "plushine.txt v1" > plushine.txt # 新建文件 
 git add ./
 git commit -m "2 commit for plushine.cn v1 from plushine"
 git push origin master # 推送到远程仓库- 运行结果:   
- 补充:本地分支、远程分支、跟踪分支(远程跟踪分支,本地分支和远程分支之间的媒介)   
更新内容
- 场景:当团队中其它成员向远程仓库中提交了新的代码,就需要将自己电脑上的内容更新 
- 案例:更新项目经理电脑上的内容 - 1 
 2
 3
 4- ll # 查看文件列表 
 git remote -v # 查看别名
 git fetch 别名 # 内容会更新到跟踪分支上
 ll # 再次查看文件列表- 运行结果:   - 1 
 2
 3- git status # 切换分支前保证分支干净 
 git checkout 跟踪分支 # 切换当前分支到跟踪分支
 ll # 查看文件目录- 运行结果:   - 1 
 2
 3- git checkout master # 切换分支到master 
 git merge taobao/master # 将跟踪分支内容合并到本地分支
 ls # 查看文件目录- 运行结果:   
push和pull
- 如果本地分支跟踪了远程跟踪分支就可以直接使用git push和git pull命令上传和拉取文件,否则: - 上传:git push 别名 分支名
- 拉取:git fetch 别名,git merge 远程跟踪分支
 
- 判断是否跟踪: - 1 - git branch -vv # 查看本地分支是否跟踪远程跟踪分支 - 运行结果:   - 注意:上图中存在联系即代表已跟踪,不存在联系代表未跟踪 
- 如何让本地分支跟踪远程跟踪分支 - clone仓库时本地分支会自动跟踪远程跟踪分支(成员可直接执行 git push 和 git pull 命令) 
- 在新建分支时,可以让本地分支跟踪指定的远程跟踪分支: - 1 
 2- git checkout -b 本地分支名 跟踪分支名 # 新建本地分支,并让本地分支跟踪远程跟踪分支 
 git checkout --track 远程跟踪分支名 # 新建与远程跟踪分支同名的本地分支,并让本地分支跟踪远程跟踪分支- 注意:存在远程跟踪分支时才能使用该命令,可以使用 - git fetch命令生成远程跟踪分支
- 让已存在的本地分支跟踪远程跟踪分支: - 1 - git branch -u 远程分支名 - 注意:同时存在本地分支、远程跟踪分支时才能使用该命令(git lol判断是否存在) 
 
- 案例:a、b两个文件夹分别代表团队项目经理和成员,模拟使用 git pull 和 git push 命令 - a中创建分支zdy和文件zdy.txt: - 1 
 2
 3
 4- git checkout -b zdy # 创建并切换到新分支 
 echo 'zdy.txt v1' > zdy.txt
 git add ./
 git commit -m "2 commit for zdy.txt v1 from a"- 运行结果:   - 1 
 2- git push # 上传分支 
 git push git-study zdy # 上传分支- 运行结果:   - 注意: - 新分支要用 git push 别名 分支名上传,git branch -u也无法创建联系,因为没有远程跟踪分支
- 执行命令 git push git-study zdy后,git会自动创建远程跟踪分支,但本地分支并不会自动跟踪它
 
- 新分支要用 
- b从仓库获取zdy分支并修改zdy.txt文件: - 1 
 2
 3- git pull # 成员b克隆仓库代码后本地分支会自动跟踪远程跟踪分支,所以可以使用git pull命令 
 git lol
 git checkout --track origin/zdy # b中创建zdy本地分支,并跟踪远程跟踪分支- 运行结果:   - 1 
 2
 3
 4- vim zdy.txt 
 git add ./
 git commit -m "3 commit for zdy.txt v2 from b"
 git push # 上传修改- 运行结果:   
- a再次获取zdy分支内容: - 1 
 2
 3- git pull # 拉取仓库 
 git branch -u git-study/zdy # 让本地分支跟踪远程跟踪分支
 git pull # 拉取仓库- 运行结果:   - 1 - cat zdy.txt - 运行结果:   
 
远程冲突
- 冲突场合:本地操作(典型合并)、远程协作(push、pull) 
- 案例1:模拟并解决push冲突(a为项目经理,b为团队成员) - 仓库内容:   
- a中修改a.txt并push到远程仓库: - 1 
 2
 3
 4- vim a.txt 
 git add ./
 git commit -m "2 commit for a.txt v2 from a"
 git push git-study master # 本地分支未跟踪远程跟踪分支,不能使用git push命令- 运行结果:   
- b也修改a.txt并push到远程仓库: - 1 
 2
 3
 4- vim a.txt 
 git add ./
 git commit -m "2 commit for a.txt v2 from b"
 git push- 运行结果:   - 上图提示:当前推送所修改的内容在仓库已经做了修改,可以先git pull 拉取仓库内容,解决冲突后重新推送 
- b中拉取仓库内容: - 1 - git pull - 运行结果:   - 1 - vim a.txt # 修改冲突 - 运行结果:   - 1 
 2
 3- git add ./ # 告知git冲突已经解决 
 git commit -m "4 commit for fix a.txt conflict"
 git push # 再次推送- 运行结果:   
 
- 案例2:模拟并解决pull冲突(a为项目经理,b为团队成员) - 在案例1基础上,a拉取仓库内容: - 1 
 2
 3- git branch -u git-study/master # 本地分支跟踪远程跟踪分支 
 git pull # 拉取仓库内容
 cat a.txt # 查看文件内容- 运行结果:   
- a中修改a.txt文件并推送到远程仓库: - 1 
 2
 3
 4- vim a.txt 
 git add ./
 git commit -m "5 commit for a.txt v3 from a"
 git push- 运行结果:   
- b中修改a.txt文件,提交后使用git pull命令拉取仓库内容: - 1 
 2
 3
 4- vim a.txt 
 git add ./
 git commit -m "6 commit for a.txt v3 from b"
 git pull- 运行结果:   - 1 
 2
 3- vim a.txt # 解决冲突 
 git add ./ # 告知git冲突已解决
 git commit -m "7 commit for fix a.txt conflict"- 运行结果:   
 
Pull Request
- 场景:当你想要参与修改某个项目,但没有推送权限,这时可以对这个项目进行“派生”(fork,在你的github空间中创建一个完全属于你的项目副本),将自己的修改提交到派生出的项目副本中并创建PR(Pull Request)请求,项目所有者审核同意后你所修改的内容就会进入源版本库。   
- 基本流程: - fork项目,clone副本项目到工作区
- 修改文件,push到仓库,创建PR
- 项目所有者审核,提交成功(失败)
 
- 案例:模拟使用PR(xingjiahui:项目创建者,PluShine:无推送权限但想参与修改) - fork项目:   - fork后PluShine新增了项目副本仓库:   
- 克隆副本仓库,push修改内容: - 1 - git clone https://github.com/PluShine/git-study.git - 运行结果:   - 1 
 2
 3
 4- vim a.txt 
 git add ./
 git commit -m "7 commit for a.txt bug fix from PluShine"
 git push- 运行结果:   - 进入仓库,创建Pull Request:   - PR创建成功:   
- 项目创建者审核PR:   - 合并提交:   - 合并成功:   
 
不足之处,欢迎留言,会及时回复,及时更正!
创作不易,感谢支持!





