1. GIT概述
1.1 GIT 安装
所有都点击【NEXT】,在【Adjusting your PATH environment】一步选择【Use Git from Git Bash only】
1.2 GIT在本地的结构
1.3 GIT 和 代码托管中心
GitHub是GIT的一个代码托管中心;代码托管中心的任务是维护远程库(git可以管理本地库)
- 在局域网环境下:GitLab服务器作为git的代码托管中心
- 在外网下:GitHub和码云可作为git的代码托管中心
1.4 本地库和远程库
-
团队内部协作
-
跨团队协作
2. GIT命令行操作
2.1 初始化本地库
git init
注意:.git
目录中存放的是本地库相关的子目录和文件,不要删除,也不要随意修改
2.2 设置签名
- 形式
用户名: xiaofun
Email地址:org@gmail.com - 作用
区分不同开发人员身份 - 辨析
此处设置的签名和登陆远程库(代码托管中心)的账号、密码没有任何关系 - 命令
项目级别/仓库级别: 仅在当前本地库范围git config
git config user.name xiaofun
git config user.email org@gmail.com
系统用户级别:登陆当前操作系统的用户范围 git config --global
git config --global user.name xiaofun
git config --global user.email org@gmail.com
优先级别:就近原则:项目级别优先于系统用户级别,二者都有时采用项目级别的签名;二者都没有不允许,一般为了方便设置系统用户级别即可,一次设置,终身可用。
如上图通过查看 .git/config
文件查看配置的内容,如果配置了系统用户级别,可以在home目录下查看,即cat ~/.gitconfig
,如下图所示
2.3 具体版本控制操作
- 查看工作区和暂存区的状态
git status
- 提交文件到暂存区
git add file
新建一个文件test.txt
,使用git status
查看状态,然后使用git add files
提交到暂存区,再查看状态
- 从暂存区撤回提交操作
git rm --cached file
- 从暂存区提交到本地库
git commit file
可以直接使用git commit -m "commint message" file
来进行提交,这样不需要进入vim编辑器写提交信息,而直接提交
2.4 版本的前进和后退
首先对test.txt
进行修改,然后提交,如下图所示(即进行了版本更新)
-
查看提交历史记录记录
git log
git log --pretty=oneline git log --oneline git reflog
当有很多提交版本信息时可以使用git log --pretty=oneline
来查看提交记录
也可以使用git log --oneline
来显示提交记录
可以使用git reflog
可以显示指针需要移动的步数
注意:若提交记录过多会多屏显示,则:空格向下翻页,b向上翻页,q退出 -
基于索引值前进后退版本【最好】
git reset --hard 索引id
-
基于^符号的版本改变
注意该方法只能往后退,不能往前;一个^
后退一个版本,两个^^
后退两个版本,如此类推,指令git reset --hard HEAD^^
-
基于~符号的版本改变
该方法只能后退,不能前进,指令git reset --hard HEAD~n
,后面n表示后退几步
-
reset 参数
hard
soft
mixed
说明
soft
仅仅在本地库移动HEAD指针
mixed
在本地库移动HEAD指针,重置暂存区
hard
在本地库移动HEAD指针,重置暂存区,重置工作区
2.5 删除文件及永久删除文件后找回
使用rm file
指令删除文件后也需使用git add
和git commit
进行提交才曾对本地库进行改变,永久删除,如下图展示了创建文件及删除。
经过如上操作后,本地库仍然保存历史版本和删除等记录,如下图所示
使用版本变换重新找回删除的文件
2.5 暂存区中文件被删除后找回
如果删除本地文件添加到暂存区,当未提交到本地库中,现在想恢复本地文件,那么还是使用git reset --hard id
来恢复上一版本即可
2.6 比较文件差异
git diff fileName
将工作区中的文件和暂存区进行比较
git diff [本地库中历史版本] [文件名]
将工作区中的文件和本地库中历史记录比较
git diff
比较多个文件,将当前目录下的文件都进行比较
2.7 GIT分支
分支的好处:
- 同时并行推进多个功能开发,提高开发效率
- 各个分支在开发过程中,如果某个分支开发失败不会对其他分支有任何影响,失败的分支删除重新开始即可
2.8 分支操作
git branch -v
查看所有分支git branch hot_fix
创建一个新的分支名字为 hot_fixgit checkout hot_fix
切换到 hot_fix 分支上
- 合并分支(比如合并到master分支上)
- 首先要切换到master分支上
git checkout [分支名]
- 执行merge指令
git merge [分支名]
- 解决合并分支产生的冲突
当两个分支里的文件都发生改动且改动位置相同时,就会产生冲突,如下图所示在test.txt
中的同一行修改,merge
后冲突。
重新进入test.txt
后发现一些新的内容
对该文件进行修改,然后保存退出,使用git add
git commit -m "info"
进行merge的最后操作
注意此处的git commit -m "info"
不能带文件名,否则报错 - 总结
- 编辑文件,删除特殊符号
- 把文件修改到满意程度,保存退出
git add [filename]
git commit -m "info"
,此时commit一定不能带具体文件名
2.9 将本地库推送到远程
git remote -v
查看地址别名
git remote add [name] [address]
,给远程仓库地址取别名
git push [远程主机名] [本地分支名]:[远程分支名]
将本地仓库推送到远程仓库;在弹窗中输入用户名密码即可。如果本地分支名和远程分支名相同,可以审略莫阿后以后的内容git push [远程主机名] [本地分支名]
实例: 将本地master分支推送到远程master分支,下面的命令相当于git push origin master:master
2.10 克隆操作
命令:git clone [address]
三个效果:
- 完整的将远程库下载到本地
- 创建origin远程地址别名
- 初始化本地库【在本地有 .git 文件】
2.11 邀请成员加入团队
新成员响应邀请后,即可push到该远程仓库中
2.12 远程修改的拉取
pull
= fetch
+ merge
- 当新成员对文件修改并提交到远程库后,远程库的创建者可以使用
git fetch origin master
将其取回,但是此时并不会改变本地工作区的文件git fetch [远程库地址别名] [远程分支]
- 若先查看取回的东西,需要先切换分支
git checkout origin/master
,然后在查看文件内容
- 使用
git checkout master
返回主分支后再用git merge origin/master
进行合并git merge [远程库地址别名/远程分支名]
pull
操作就是上面的fetch
和merge
操作的合并,直接用pull,无法查看新加入成员修改内容,对于复杂的修改,应先查看修改内容,确保没问题再merge
git pull [远程主机名] [远程分支名]:[本地分支名]
git pull origin master:brantest
将远程主机origin的master分支拉下来,与本地brantest分支合并- 如果远程分支与当前所在分支合并,冒号后面部分可以省略
git pull origin master
2.13 协同开发时冲突解决
两个团队都改了同一个文件同一个位置就会发生冲突
- 如果不是基于GitHub远程库的最新版所作的修改,不能推送,必须先拉取(pull),拉取下来如果进入冲突状态,则按照“分支冲突解决”操作即可
2.14 跨团队写作演示
- 团队2
fork
团队1的项目
- 团队2将fork的项目clone到本地;在本地对项目修改,然后push到远程库
pull request
—>New pull request
-->Create pull request
- 团队1看到团队二发来的request可以查看代码,确保没有错误的情况下
Merge pull request
合并代码—>填写提交的log信息,confirm merge
2.15 使用SSH免密登陆
-
cd ~
来到home 目录;rm -r .ssh/
删除以前生成的ssh; -
ssh-keygen -t rsa -C [github 邮箱]
,此时在.ssh
目录下会生成id_rsa
和id_rsa.pub
两个文件; -
复制
id_rsa.pub
文件内容 -
在如下界面中点击
New SSH KEY
,然后粘贴
-
回到Git Bash 创建远程地址别名
git remote add [Name] [ssh address from github]
2.16 给代码打标签tag
如果当前代码开发到一个重要阶段,并希望永远记住那个特别的快照,可以使用git tag给他打上标签。比如robot项目发布一个1.0版本
,可以使用git tag -a v1.0 -m '发布1.0版本'
命令给最新一次提交打上v1.0标签。-a
选项为创建一个带注解的标签
,-m
带上具体注解。不用-a
也可执行,但他不会记录这标签是什么时候打的,不会增加注解
- 创建一个带注解的标签
git tag -a v1.0 -m '发布1.0版本'
- 查看所有标签
git tag
一般是在master分支上打tag,总的流程如下:
- 切换到master分支:
git checkout master
- 拉取最新代码:
git pull origin master
- 在master分支上创建tag:
git tag -a v1.0 -m '发布1.0版本'
- 推送tag:
git push origin v1.0
在使用过程中可以直接使用git checkout [标签名]
切换到指定版本
2.17 submodule
对于较复杂的项目,不可避免地会引用一些公共基础库,或是将代码拆解成公共模块和多个子模块进行管理,主项目工程中的子模块需要对公共模块有依赖关系,却又不必关心公共模块内部的开发流程细节,若直接将公共代码复制到项目中显然是不合适的,因为不方便更新维护。关于公共模块的管理有很多成熟的实践,常见的有 npm 和 git submodule 两类方式。
简单来说submodule的作用就是在已有的代码库中再嵌入一个子代码库,但是子代码库并不会进行改动,只是当前项目对其有依赖。
-
创建 submodule
创建submoduel非常简单,只要执行如下命令即可git submodule add <submodule_url> <submodule_local_path>
<submodule_url>
就是子代码库的git链接,直接到子代码库去查找
<submodule_local_path>
是子代码库clone下来在当前的代码库的目录
当然也可先进入要clone的目录下,然后直接运行如下代码git submodule add <submodule_url>
上述完成以后,项目中会多出两个文件:
.gitmodules
和子模块项目文件夹,然后执行git commit
即可 -
获取 submodule
当我们clone一个带有子模块的代码库时,你会发现clone完以后子模块是一个空目录,此时我们需要来初始化并更新子模块,执行如下两条命令即可git submodule init # 初始化本地配置文件 git submodule update # 检出对应的 commit id 的子项目
也可以在 clone 命令中添加
--recurse-submodules
或--recursive
参数递归拉取子模块代码git clone --recursive /path/to/repos/foo.git
2.18 git stash
- 应用背景
- 发现有一个类是多余的,想删掉它又担心以后需要查看它的代码,想保存它但又不想增加一个脏的提交。这时就可以考虑git stash
- 不想提交完成一半或者不完善的代码,但是却不得不切换分支去修改一个紧急Bug或做其他事情,那么使用git stash就可以将你当前未提交到本地(和服务器)的代码推入到Git的栈中,这时候你的工作区间和上一次提交的内容是完全一样的,所以你可以放心的修Bug,等到修完Bug,提交到服务器上后,再使用git stash apply将以前一半的工作应用回来
- git stash 的用法
# 保存当前未完成的工作 git stash # 或者使用下面的命令在保存当前未完成工作的同时提交一个message,便于查看,防止多次stash,无法区分 git stash save 'your message' # 下次回来继续工作时可先查看有哪些保存的节点 git stash list # 恢复上次未完成的工作 git stash pop
- 注意
- stash是本地的,不会通过git push命令上传到git server上。实际应用中推荐给每个stash加一个message,用于记录版本,使用
git stash save
取代git stash
命令 git pop
将缓存堆栈中的第一个stash删除,并将对应修改应用到当前的工作目录下,也可以使用git stash apply
命令,将缓存堆栈中的stash多次应用到工作目录中,但并不删除stash拷贝,在使用git stash apply
命令时可以通过名字指定使用哪个stash,默认使用最近的stash(即stash@{0})- 可以使用
git stash drop
命令移除stash,后面可以跟着stash名字,apply和drop时需要的名字都可以通过git stash list
获取
- stash是本地的,不会通过git push命令上传到git server上。实际应用中推荐给每个stash加一个message,用于记录版本,使用
- 参考:git stash 用法小结
3. GitFlow工作流
3.1 分支种类
- 主干分支 master
主要负责管理正在运行的生成环境代码,永远保持与正在运行的生产环境完全一致 - 开发分支 develop
只要负责管理正在开发过程中代码,一般情况下应该是最新的代码 - bug 分支 hotfix
主要负责管理生产环境下出现的紧急修复代码,从主干分支出,修理完毕并测试上线后并回主干分支。并回后,视情况可以删除该分支。 - 准生产分支 release
较大的版本上线前,会从开发分支中分出准生产分支,进行最后阶段的集成测试。该版本上线后,会合并到主干分支。生产环境运行一阶段较稳定后可视情况删除 - 功能分支 feature
为了不影响较短周期的开发工作,一般把中长期开发模块,从开发中独立出来。开发完毕后会合并到开发分支中
3.2 GitFlow工作流举例
4. GitLab服务器搭建过程
4.1 官网地址
GitLab是局域网内的代码托管中心
首页地址: https://about.gitlab.com/
安装说明: https://about.gitlab.com/installation/
可以参见第五章参考中的视频最后三集
5. note
5.1 团队合作只提交dev自己部分到master
- 在dev分支上
git pull
(前提是所有改变都已提交) git checkout master
切换到master分支, git pull 拉最新代码git checkout dev xxxx
(xxxx为已经改动的代码路径或目录)git commit -m "xxx"
git push origin master