Git基础知识
了解Git的工作原理和基本操作,从此不在为记不住命令而抓狂
Git是一个开源的分布式版本控制系统,可以快速高效的处理从小型到大型的各种项目。
何为版本控制
版本控制是一种记录文件内容变化,以便将来查阅特定版本修订情况的系统,让用户可以查看历史修订版本。举个简单的例子
这张图大家应该都经历过,一篇论文经过反复的修改,我们就要不停的copy备份,还不敢随便的删除原文档。既占空间又显得臃肿,我们写代码,做项目,又是一个团队协作的事情,你也改,我也改,那么这篇文档将会显得十分“庞大”,而使用Git的版本控制就可以只保留一份文档,当想要回到原来的任意版本都只需要一个简单的命令。
几个概念
工作区:写代码、项目修改的地方
暂存区:临时存储、准备下一次提交
本地仓库:存储历史版本
远程仓库:团队成员共享项目代码
常用命令
在上面这张图中我们也看到许多git的命令,现在我们来简单的介绍他们
命令名称 | 作用 |
---|---|
**git add 文件名 ** | 添加到暂存区 |
**git commit -m “日志信息” 文件名 ** | 提交到本地库 |
git clone | 从远程仓库克隆一个完整的仓库到本地 |
git fetch | 从远程仓库获取最新的数据(通常是分支的最新提交)到本地,但不会自动合并或检出这些更改 |
git checkout | 检出(或切换)到指定的分支或提交 |
git pull | 从远程仓库获取最新的数据并尝试合并到你的当前分支 |
git push | 将本地分支的更改推送到远程仓库 |
其实除了这几个命令外,我们还有一些前期的初始化命令(划重点,后面要考):
命令名称 | 作用 |
---|---|
git config --global user.name | 用户名 设置用户签名 |
git config --global user.email | 邮箱 设置用户签名 |
git init | 初始化本地库 |
git status | 查看本地库状态 |
git reflog | 查看历史记录 |
git reset --hard | 版本号 版本穿梭 |
我们用原生的Git Bash
简单的过几条命令
- 在新建的空白目录GitTest下右键选择
Git Bash
,打开Git的doc界面,设置基本的git提交信息,该信息是你提交代码时的用户信息
-
使用
git init
命令初始化仓库
可以明显的看到运行完git init
后左边文件目录下出现了.git
文件,它存储了版本控制所需的所有信息
-
运行
git status
发现没有任何提示变化,新建hello.txt
文件,运行git status
后,报错提示有未追踪的文件 -
使用
git add
将文件添加至暂存区,再次运行git status
,不再报错,但是提示我们需要commit
-
使用
git commit
命令提交文件,运行git status
正常显示了
-
接下来就是设置远程仓库、pull
、push
等等,推送远程仓库之前需要设置远程仓库地址
git remote -v # 查看当前远程仓库地址
git remote add origin https://github.com/username/repo.git # 如果没有,添加一个
这里就不再使用doc
界面展示,转战场至IDEA
,IDEA
对Git
做了很好的集成
清空刚刚的GitTest
文件目录,使用IDEA
打开。
在弹出框中填写远程的地址
新建一个Application.java
测试文件,弹出框的提示让你想到了那个命令,没错就是git add
点击添加完后,我们就可以看到左下角的原本的版本控制变成了Git
,点开如下所示,这相当于那个命令?—git status
在这里未进行版本管理的文件全部都是.idea
文件夹中的内容,而这个文件夹它包含了个人本地IDE的配置信息,不同用户或不同环境之间的配置可能存在差异,避免在版本控制中造成不必要的冲突我们一般将他排除。
在版本控制中我们新建.gitignore
文件,在该文件中使用正则的方式写需要排除的文件,在该文件夹中记录的文件在项目的记录中就不会被提交
可以看到,.idea
文件夹中的文件已经不会被版本控制了。接下来提交我们修改好的文件【这一步就相当于git commit
】
为你的提交写一个注释或者说记录
我们可以在Git的日志看到,已经成功的加入本地仓库【注意此时是绿色的线条】
将我们刚刚存到本地仓库的代码git push
到远程仓库中
push
成功可以看到此时这条日志主线便成为了暗黄色
我们来总结一下上面的操作都对应着那些命令
- 我们将代码从远程仓库拉取下来其实就是执行了
git clone
- 点击左下角的
Git
查看本地更改,实质上是执行了git status
- 接着我们创建文件时,会询问我们是否将文件添加到暂存区,其实就是执行了
git add
- 修改完文件后,我们在左下角进行提交至本地仓库是在执行
git commit
- 选择右上角绿色的
→
将本地仓库推送至远程仓库是在执行git push
- 绿色
✔
旁边的蓝色→
是在执行git pull
,建议在每次push
前先pull
- 通过日志查看提交记录其实就是在运行
git relog
或者说git log --graph
分支管理
分支的创建、合并和删除,分分钟变成多线程代码管理高手
在我们的日常工作中,往往不是"串联"电路,而是"并联",我们需要同时推进多个任务,那么我们就可以把自己的工作从开发主线上分离开来,开发自己的分支,而不影响主线的运行
命令名称 | 作用 |
---|---|
git branch 分支名 | 创建分支 |
git branch -v | 查看分支 |
git checkout 分支名 | 切换分支 |
git merge 分支名 | 把指定的分支合并到当前分支上 |
git branch -d 分支名 | 删除分支 |
git branch -D 分支名 | 当分支含有未提交文件会阻止删除,使用-D强制删 |
git push origin :分支名 | 删除远程仓库分支名 |
接下来演示分支管理
点击右下角的master
分支可以看到远程仓库有两个分支,master
是主线分支,我们平时的开发提交一般都是提交到dev
分支,在经过代码的检查审核没有问题后才会合并到master
分支,我们本地也可以创建一个dev
分支,值得一提,小书签所指示的分支就是你当前所在的分支
新建完分支后会自动切换到该分支,我们添加一行代码,进行add、commit
后切换回master
分支
如下图,我们可以看到,dev
分支中的代码并没有影响到master
,做到了代码开发上的隔离
当我们的项目经理或者开发者检查运行完dev
中的代码没问题后就可以进行代码的合并
我们还可以通过日志查看本次合并做了那些修改
突然,项目经理觉得这些写不对!需要先把原来的代码撤回回去,那么我们就可以这么做
我们可以将我们本地的dev
分支与远程仓库的dev
分支建立关系,当我们在dev
分支拉取代码时,因为没有设置上游分支,它会提醒我们,我们进去配置就好
合并远程dev
分支和master
分支和本地的方法一样,也是使用merge
冲突解决
学会如何优雅地解决冲突,不再因为merge而想摔键盘
冲突产生的原因:
合并分支时,两个分支在同一个文件的同一个位置
有两套完全不同的修改。Git 无法替
我们决定使用哪一个。必须人为决定
新代码内容。
首先来制造冲突,在master
和dev
中分别修改语句
试图进行分支合并
果然出现了报错
选择合并进行人工手动合并,解决冲突
左边的是你所在的分支master
,中间的是原本的代码,右边的是你想要合并的dev
分支的代码,选择×
就是删除这行代码,选择》
或者《
就是接收相应的左边或右边的代码,点击应用,合并完成,代码冲突解决,自动提交本地库。
疑难杂症与常用技巧
实用的Git技巧和命令,让你在团队面前炫技无压力
1. git add 提交文件到暂存区时报错
error: 'project/' does not have a commit checked out fatal:
adding files failed
或者上传的文件夹变成了一个不可打开的文件,形式是文件名+@+一串数字
原因: 提交项目子目录中有.git文件(可能是隐藏状态),显示隐藏文件即可,找到 .git 文件夹,删除!
2. 提交项目到远程仓库时报错
$ git push -u origin main
error: src refspec main does not match any
原因:提交到远程仓库中的分支和本地的仓库的分支不一样,例如代码块中的分支是master,但是gutlab主分支是main,修改本地分支名称即可
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'https://github.com/xxxxxx'
原因:远程仓库中的代码比本地仓库中的新(存在本地仓库没有的文件),这也就是我说为什么push
之前先pull
3. 使用了魔法导致错误
curl 28 OpenSSL SSL_read: Connection was aborted, errno 10053
fatal: error reading section header 'shallow-info'
解决:使git忽略ssl证书错误
git config http.sslVerify "false"
4. git push出现“Everything up-to-date”
原因:没有git add
、没有git commit
,如果你发现不是这两个原因,看看你是不是创建了一个空目录,空目录下必须有文件才能push
成功,为此我们可以在空目录下创建一个.gitkeep
文件,这也算是一个小技巧
5. git commit后如何撤销或修改
修改了本地的代码,然后使用git add
和git commit
执行commit后,还没执行push时,想要撤销这次的commit,该怎么办?
解决方案:
git reset --soft HEAD^
这样就成功撤销了commit,如果想要连着add也撤销的话,–soft改为–hard(删除工作空间的改动代码)。
命令详解:HEAD^
表示上一个版本,即上一次的commit
,也可以写成HEAD~1
;如果进行两次的commit
,想要都撤回,可以使用HEAD~2
--soft不删除工作空间的改动代码 ,撤销commit,不撤销git add file
--hard删除工作空间的改动代码,撤销commit且撤销add
6.git
文件名大小写变更后未产生变化问题处理
原因是默认git配置了忽略大小写敏感
$ git config core.ignorecase true
//下面设置大小写敏感为敏感
$ git config core.ignorecase false
高级功能
探秘子模块、钩子和重新基线,开启Git的高级玩法
以使用HEAD~2
--soft不删除工作空间的改动代码 ,撤销commit,不撤销git add file
--hard删除工作空间的改动代码,撤销commit且撤销add
6.git
文件名大小写变更后未产生变化问题处理
原因是默认git配置了忽略大小写敏感
$ git config core.ignorecase true
//下面设置大小写敏感为敏感
$ git config core.ignorecase false
高级功能
探秘子模块、钩子和重新基线,开启Git的高级玩法