git
一.分支介绍
1. 1 分支结构
分支分为三种:master dev feature三种
1.2 分支特点
master和dev面向项目管理人员, feature面向开发人员
- master: 稳定运行版本,不可以在此分支开发,master永远只有一个。
- dev:开发主分支,该分支只做只合并操作,不能直接在该分支上开发,该分支由项目管理人员基于master创建。
- feature :面向开发人员的分支,由开发人员基于最新的dev分支在git bash手动创建 。
1.3 分支总结
- master和dev分支是项目管理人员创建的,不是开发人员创建的。
- 开发人员不要在 master和dev分支上做任何修改。
- 开发人员牢记一点,你只能在你自己创建的分支上写代码,你的分支基于dev分支手动创建的。
二.个人规范
2.1 个人分支命名规范
为了方便识别分支信息,在建立自己的开发分支时采用统一模式的命名方便识别:
feature/姓名拼音 + 功能(多个英文单词用"-"分割,英文单词全用小写,应尽量做到言简意骇)
比如:feature/penggan-city-manager
2.2 git commit 规范
姓名 + 行为+“:”+描述信息
行为主要三种add alter delete
例: penggan add:xxxxx
例:penggan alter:xxxxxx
例:penggan delele:xxx
三.操作案例
3.1 建立一个空文件夹
此文件夹用于存储clone下来的项目包,进入此目录,在此目录内右键鼠标进入git bash
3.2 登录Gitlab 找到需要clone的项目地址
3.3 在git bash进行下面的操作
1. git clone 项目链接,此时你会你的文件夹中会多出一个目录,这个目录就是下载的远程仓库
2. cd 下载的仓库// 进入仓库(注意这一步是基础,只有进入仓库才能继续接下来的)
3. git checkout master //先切换到master主分支
4. git pull //在主分支下运行pull会把远程仓库中的所有分支都下载到本地电脑
5. git branch//查看所有的分支,找到最新的dev分支,你要基于最新的dev建立自己的开发分支
6. git chackout dev-xxx //
7. git branch feature/xx //建立自己的开发分支
8. git push -u feature/xx //将开发的代码推送到远程仓库
四.Git bash常用命令
1. git branch //查看本地分支。
2. git branch -a //查看所有分支
3. git branch -r //查看远程分支
4. git branch +分支名称 //新建分支
5. git checkout +分支名称 //切换分支
6. git branch -d +分支名称 // 删除本地分支, 代码搞乱了又不想回退版本,可以直接删了,然后重建
7. git add . //将修改加入缓存区
8. git commit -m "描述信息" //生成一个本地版本
9. git push -u 分支名称//将本地分支提交到远程,如果远程已经有了此分支,可简化成git push
10. git log 可以查看本地所有commit的版本
11. git reset --hard 0090e3e7571931d2a08b95bde770790fd96028f2//回退到某个commit版本
12. cd test //进入test目录
13. ls test //列出test目录下所有文件
14. mkdir test //创建一个test目录
15. pwd //显示当前路径
16. clear //清除shell终端
17. history //查看执行过的命令
五. 常见错误
The current branch develop has no upstream branch:
5.1 情况一:没有对应的远程分支
- 解决方法:git push -u origin dev(远程分支名)
- 这条语句会执行三个步骤:
- 建立对应的远程分支,在本例中为dev分支。
- 关联本地分支和远程分支,在本例中是将本地的dev分支和远程的dev分支关联。
- 完成代码的推送。
5.2情况二:有对应的远程分支,但两者的关联失效
- 解决方法:git push --set-upstream origin dev
- 这条语句会执行两个步骤:
- 关联本地分支和远程分支,在本例中是将本地的dev分支和远程的dev分支关联。
- 完成代码的推送。
六.关于git push主机的概念
所谓的主机,意思是说你有多个gitlab服务器,比如一个测试机器一个是线上机器,实际上大多数公司只用一个gitlab.
但是理解这些是很有必要的。
git push与git push的核心语法解读
git push <主机名> <本地分支>:<远程分支>
git pull <主机名> <远程分支>:<本地分支>
- git push origin test
如果省略远程分支名,则表示将本地分支推送与之存在"追踪关系"的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。
上面命令表示,将本地的test分支推送到origin主机的test分支。如果后者不存在,则会被新建。
- git push origin :test
如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。
等同于git push origin --delete test
- git push origin
如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。 上面命令表示,将当前分支推送到origin主机的对应分支。
- git push
如果当前分支只有一个追踪分支,那么主机名都可以省略。什么叫只有一个追踪分支。
比如公司有两个远程仓库,你本地分支推送了到两个仓库中,也就意味着对你本地分支而言,你有两个远程追踪分支,那么在push 的时候就不能那么随意的省略主机名也意味着你必须用:git push origin
- git push -u origin test
如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样后面就可以不加任何参数使用git push。
- git push -u origin test
上面命令将本地的test分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了。
后面git push 则意味着将分支推送到origin主机对应的分支。
- 再谈git push
对我们来说,目前只有一个Gitlab仓库,也就意味着只有一个主机名,大多数时候git push就可以了。但是要注意git
push意味着远程仓库已经有一个追踪分支。如果是你本地新建的分支那么远程仓库还没有对应的追踪分支,故而第一次的时候不能用 git push
而应该用:git push origin test或者git push -u origin test 建立远程和本地的连接
- 注意事项
在用git push无任何参数的时候。默认把当前分支推送到默认主机名 对应的远程仓库的追踪分支上。这里有个需要特别注意的词语:当前分支。
在用此命令的时候,请确保你在要推送的分支中,否则需要git checkout 分支名, 然后再次运行此命令。
最后,如果你是一个新手,请尽量不要用git push无参数的命令. 而是应该用git push origin 分支名,这才是安全的行为。
七.其他进阶命令
1. git rev-parse
git rev-parse 不加参数 查看当前分支的最新一次提交的 commitID
git rev-parse 分支名 查看当前分支的最新一次提交的 commitID
2. git show
git show 无任何参数 ,表示查询当前分支最后一次提交的改动信息
git show commitID, 表示查询指定commitID 的改动信息
git show 分支名, 表示查询当前分支最后一次提交的改动信息
git show --name-only 发生改动的文件列表
git show --pretty=format:[%H][%an][%d] 格式化输出:commitID, 提交人, 引用
3. git status
只会展示文件不会展示 目录
1. 绿色部分指的是 【已git add 未git commit的文件】
2. 中间部分指的是 【未 git add 的文件】
3. 下面部分指的是 【新建的文件(在工作空间中未被追踪的新文件)】
4. git clean
这是一个危险的操作,使用者必须明确知道自己在做什么。
熟悉git clean之前,务必先看上文的git status
git status 会列出新建的文件,新的文件在过往历史中是从未被追踪的文件。
git clean 可以清除这些新建的未被追踪的文件。
git clean 支持的参数
-n 选项提供"dry run"功能,当我们运行 git clean -n 时,并不会真正的执行删除,而是会先把要删除的文件先给你列出来,然后你可以先检查一下这些文件是否需要删除。在我们真正执行 git clean
之前,我们最好都执行一次"dry run"来检查我们要删除的文件,以免发生难以逆转的删除。-f/–force 我们发现git clean 默认的行为是拒绝清理,如果我们想要发起git clean 我们得加上–force或简写为-f,这是一个很重要的安全机制,因为git clean命令是不可逆转的,它等同于你执行 rm
命令去删除文件。所以在运行git clean之前,你最好确保你知道你在干什么。Sd-X 使用 -x 选项可以删除在 .gitignore 管辖范围内的文件,当我们做一些实验时,想恢复到实验前的仓库状态,这个选项就很有用了,即便是.gitignore的文件也会被清除。(这是大写的X)
-d 默认行为【只删除文件不会删除目录】,如果你想把目录也删除掉你可以使用 -d 告诉 git clean 你想把文件夹也删除掉。
git clean 使用场景
- 当我们本地java代码想要提交到gitlab 上面时候, 在所有有效代码都commit之后, 可以运行 git clean -f -d执行清理操作,这可以把编译的target 目录干掉,这个目录是本地编译的目录,不需要提交到gitlab.
- 当开发一个自动打包的系统的时候,执行打包压缩之前可以执行 git clean -f -d 清除根目录
八. 合并分支
场景模拟:比如我们基于dev-v1.0 分支建立了本地开发分支feature/penggan-data-etl
在开的过程中我们发现dev-v1.0 版本本身有bug,然后管理在dev分支做了修改。
此时我们需要把dev的修改合并到我们正在开发的分支:feature/penggan-data-etl中。
-
第一种方式(条理清晰,推荐新手使用)
git checkout dev-v1.0 //切换到dev分支 git pull //更新本地dev分支 git checkout feature/penggan-data-etl //确保我们在自己的分支上 git merge dev-v1.0 // 将dev-v1.0中的修改合并到feature/penggan-data-etl中
-
第二种方式(作为补充知识,新手不推荐,老手推荐)
git fetch origin dev-v1.0 //获取远仓dev-v1.0的更新部分,更新部分拉到本仓库。 git checkout feature/penggan-data-etl //切换到个人分支 git rebase origin/dev-v1.0 //将dev-v1.0的更新部分插入penggan-data-etl
九.本地和远程仓库建立连接的方式
场景:假如你本地有一个代码你想把它推送到远程,而远程仓库此时并没有对应的分支。
我们知道git push 的前提是远程分支和本地分支存在关联关系的时候才可以推送,因此在推送之前必须先建立连接。否则无法推送。
-
本地初始化方式
首先,不管你用的是啥代码仓库,gitlab、github、gitee 先登录上去创建一个仓库demo吧,然后获得一个仓库的URL(https://xxx.xxx.xxx.com/xxx/xxx/demo_project.git)
下面我们就要将本地的代码目录推送到这个远程仓库;# 本地也建立一个目录名字和远程仓库的顶级目录保持一致,也叫demo #进入项目目录 cd demo #本地仓库初始化 git init #添加自己的代码,到本地仓库 git add . #添加提交信息 git commit -m "提交信息" #配置本地仓库提交远程仓库的链接,这一步骤是关键。 git remote add origin https://xxx.xxx.xxx.com/xxx/xxx/demo_project.git #把本地仓库代码推送到远程仓库 git push -u origin 分支名
-
clone方式
git clone https://xxx.xxx.xxx.com/xxx/xxx/demo_project.git 这样你本地就会出现一个demo的目录,进入demo目录,把本地的代码copy到此demo目录中 git add . git commit -m "说明信息" git push -u origin 分支名
我们发现第二种方式更简单一些,不需要运行git remote建立连接,那是因为我们clone下来的项目本身内部就保持了连接信息。
IDEA 配置git的连接
场景,我现在有个项目,此项目gitlab上不存在,我怎么直接在idea上将此项目推送到远程?
网上有很多带图的方式,此方式大家自行测试。我其实不喜欢这种方式。我推荐按照上一小节
本地和远程仓库建立连接,建立连接之后,idea直接打开就可以了,直接可用。
因为idea读取你的项目发现是git项目,而且你初始化的时候已经建立的连接。
此时, idea会自动连接,不需要额外做什么配置。
八.深入理解 git fetch git pull
8.1 git checkout 注意事项
在本地git checkout 切换分支之前,如果此时远程分支有了一个新的分支,我们本地直接git checkout ‘远程新分支’ 是会报错的,即便你在本地运行git branch -r 查看远程分支也会惊喜的发现,返回结果并不包含远程的新分支,这是因为本地并未更新.因此可以再checkout 之前,再任何一个分支运行:git fetch 或者git pull
8.2 git fetch 和git pull 注意事项
在任何分支运行git fetch 和 git pull 都会更新本地分支的元数据信息, 意思是让远程新建的分支,或者是远程有新的提交的分支的信息 在本地可见。
当信息可见之后,我们要同步具体的分支,依旧需要git checkout 分支名,然后git pull
8.3 更新本地分支的两种方法
假设本地有dev-test 分支,远程的dev-test被同事更新了。我们想同步远程的更新,此时有下面两种方法,假设此时我们在master分支。
-
git fetch && git merge
- git fetch 拉取所有远程更新到本地缓存,也就是会将更新存到本地 origin/分支名称 中
- git checkout dev-test 切换要被更新的分支
- git merge origin/dev-test 将本地远程分支的更新部分合并到本地dev-test分支
git merge dev-test 则不会起到任何效果, origin/dev-test是远程分支在本地的缓存,更新的代码就在 origin/dev-test 上 因此我们要用git merge origin/dev-test 而不能用git merge dev-test 这样会将远程分支本地缓存更新的部分合并到本地分支 dev-test
-
git pull
- git checkout dev-test
- git pull
-
例子探讨
在你的本地机器上运行 git branch -l 看到的本地分支。
git branch -r 看到的远程分支。
上面两个列表本质上全都是本地的分支。
网上说git branch -r 查看远程分支其实不是真的远程分支。
只不过是本地缓存的 远程分支,不是真的远程分支。
当远程仓库新增一个真的远程分支的时候,你在本地运行git branch -r是看不到的。
必须运行git fetch 更新本地缓存才能看到。
所以:git branch -l 查看的是我们本地自己操作的分支 git branch -r 查看的是远程分支在本地的缓存,本质上依旧是本地分支 git fetch 更新的是远程分支在本地的缓存,而不是直接更新本地分支
因此git merge 有两种写法
1. git merge 我们本地自己操作的分支(例:git merge penggan-dev-3)
2. git merge 远程分支在本地的缓存(例:git merge origin/penggan-dev-3)
上面两种写法背后的含义是完全不同的
- 第一种写法要求penggan-dev-3已经是pull过的最新的代码
- 第二种写法要求,只要在任何分支运行了git fetch 即可。
因为git fetch 会更新的是远程分支在本地的缓存,
也就是远程分支的修改已经在origin/penggan-dev-3上面了
因此直接git merge origin/penggan-dev-3就行了。
九.云端仓库dev-test被同事更新了,我想同步云端的更新有以下两种方式 :
9.1 第一种方案
1. git checkout dev-test
2. git pull
9.2 第二种方案
1. 任意分支执行git fetch;
2. git checkout dev-test;
3. git merge origin/dev-test
以上两种方式等价,第一种用的人比较多
10. 不同分支合并 例如开发中比较常见的 将dev-test 合并到master
10.1 第一种方案
1. 任意分支 git fetch;
2. git checkout master;
3. git merge origin/dev-test
10.2 第二种方案
1. git checkout dev-test;
2. git pull;
3. git checkout master;
4. git merge dev-test;
10.3 第三种方案
1. 任意分支执行git fetch;
2. git checkout dev-test;
3. git merge origin/dev-test;
4. git checkout master;
5. git merge dev-test;
以上三种方式等价,第一种和第二种用的人比较多