文章目录
一、git的由来
1.1 版本控制(Revision control)
假如,我们在开发一个产品的过程中,产品经理过来提了一个需求让我们完成。虽然一看就是个没卵用的功能,但我们还是去做了。果不其然,废了九牛二虎之力完成后,产品经理说这功能不好用又给砍掉了,要我们把源码恢复到之前的状态。没办法,这就是咱的命,老老实实做呗。
之后,我们的工作就分为两种情况:
-
如果没用版本控制,项目源码就一份,来来回回改:
完蛋,我们只能又去删除那些辛辛苦苦写出来的代码,各种接口一个个改回来,一个个修bug。(最要命的是,删完之后,产品经理又想要那个功能了😾)
-
如果用了版本控制,项目源码在开发这个倒霉的功能之前,就另外存储了一份:
只需要恢复到另外存储的那一份即可。(产品经理又想要也不怕,原来那份我们压根没删😎)
这就是版本控制最基本的用法和原理。
1.2 集中式和分布式
上面的例子中,我们是手动另存了一份源码,这只适用于简单的版本控制,版本多了之后就会使不版本库杂乱,不好控制,最重要的是不适合团队开发。于是,就有大佬们开发了一些专门用于版本控制的软件,称为版本控制系统。比如,集中式版本控制系统:CVS、SVN等,分布式版本控制系统:GIT(我们的主角)、Mercurial等。
1.2.1 集中式
集中式版本控制系统需要一个中央服务器,版本库存放在中央服务器中。开发的时候,大家从中央服务器获取一份源码到自己电脑上,开发完了就放回去。
但它有一个很大的缺点,那就是中央服务器要保护好,它要是坏了,那所有的一切就都完了。
1.2.2 分布式
分布式版本控制系统中,在每个开发人员的电脑上都有一份完整的版本库,而中央服务器是不存在的。但通常会有一个服务器充当一下“中央服务器”,被称为远程仓库,用来保证代码的安全,以及团队开发时,开发人员之间版本库的同步。
二、git的安装与配置
2.1 Ubuntu下安装
在终端中执行:
sudo apt-get install git
完成。
2.2 windows安装
到官网下载安装包:传送门,选择 Setup版本的。运行安装包,一直点下一步(next)即可。
2.3 配置
-
用户信息:
git是支持多人协作的,所以需要先配置一下我们自己的用户名和电子邮箱,用来标记更新是谁提交的(出了问题好找他算账😨)。
终端中运行:
git config --global user.name "用户名" git config --global user.email 电子邮箱
-
文本编辑器:
如果git需要我们输入一些内容的时候,就会调用配置的编辑器。
git config --global core.editor emacs # 如Emacs
-
差异分析工具:
解决冲突用的工具。
git config --global merge.tool vimdiff # 如vimdiff
-
查看配置信息:
git config --list
三、git的仓库结构
- 工作区:就是我们写代码的地方,用不用git都没有变化;
- .git文件夹:使用git初始化仓库后出现的东西,就是存放版本库的文件夹;
- 暂存区:也叫待提交区,在正式提交到版本库之前,暂时将改动后的代码通过git命令放在这里;
- 版本库:暂存区的代码通过git命令被正式提交后就会保存在这里。
另外,通常情况下还会有一个远程仓库(中央服务器)。版本库可以在远程仓库存放一份,方便团队开发和代码的安全。远程仓库可以使用现成的,比如:github(全球最大)、码云(国内常用)等,也可以公司内部使用gitlab自己搭建。
四、git基础
git既可以通过一些软件的图形界面来使用,也可以通过终端命令进行使用。(我们当然要学命令啦,虽然图形界面用的更多😟)
4.1 提交操作
-
初始化:
开始使用git进行版本控制。
git init 项目路径 # 不写路径,代表控制当前目录
-
查看状态:
确定哪些文件当前处于什么状态。
git status
假设目录下只有一个a.txt文件,则输出如下:
位于分支 master 尚无提交 未跟踪的文件: (使用 "git add <文件>..." 以包含要提交的内容) a.txt 提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
表示当前没有提交过任何更新,并且a.txt没有被git所追踪(即没被管理)。若要追踪(即进行管理),使用
git add
命令。ps:空文件夹默认会被忽略。
-
提交到暂存区(建立追踪):
git add a.txt # 将a.txt添加到暂存区
这就表示a.txt从此以后就由git进行版本控制了。如果没有这一步,a.txt的内容无论怎么修改,git一律不会管,只会显示a.txt未追踪。
如果要建立追踪的文件很多,可以用引文句号
.
代替具体文件,表示对目录下所有文件建立追踪:git add .
-
提交到版本库:
提交到版本库时,只会提交暂存区的所有文件。
git commit -m "提交说明,描述本次提交的更新内容"
没有
-m
和说明会报错。
4.2 撤销操作
-
取消暂存:
git restore --staged 文件路径
会从暂存区删除文件,不影响工作区。
-
放弃修改:
在工作区做了修改,但想丢弃这些改动,未添加到暂存区的,可以使用以下命令直接放弃。
git restore 文件路径
添加到了暂存区的,要先取消暂存。
-
查看提交历史:
git log
默认不用任何参数的话,
git log
会按提交时间列出所有的更新,最近的更新排在最上面。输出结果如下:commit 0d3b6f05fe26d8837a43f88aff5a682dc84aba5f (HEAD -> master) Author: hugh <ma.hugh@foxmail.com> Date: Fri Jan 7 11:01:40 2022 +0800 提交说明,描述本次提交的更新内容
每一行分别是提交的ID(一个SHA-1 校验和)、作者的名字和电子邮件地址、提交时间以及提交说明。
用
-p
选项展开显示每次提交的内容差异,用-2
则仅显示最近的两次更新。--pretty=oneline
简化输出内容。 -
恢复到指定版本:
如果想要恢复到版本库中的某个版本,可以使用下面的命令,它会将指定版本放到暂存区中。
使用提交ID指定要恢复的版本,取前面若干位即可(能和别的版本区别开即可),无需写全部。
git reset 0d3b6f05
也可以使用
HEAD
和^
符号指定,HEAD
后面跟一个^
代表向前一个版本,2个代表向前回退2个版本。比如回退到倒数第2个版本:git reset HEAD^^ git reset HEAD~100 # 回退100个版本
在
reset
选项后面添加--hard
参数,会直接将指定版本放到工作,覆盖工作区的数据并“删除”(实际是隐藏)回退版本之后的所有信息,所以要慎用!!! -
查看完整的提交历史:
在回退到指定版本后,发现回退版本之后的版本信息都不见了,不用害怕,用下面的命令,它会输出所有的操作记录。
git reflog
4.3 忽略文件
项目目录下有一些特殊文件其实是不属于我们项目的,比如:node_modules模块文件夹、env虚拟环境文件夹、.pyc
编译文件等等。这些文件和文件夹并不需要被git追踪管理,所以我们要进行配置,让git忽略这些文件和文件夹。
配置很简单,只需要在==.git
文件夹的同级目录下==创建一个.gitignore
文件,将要忽略的文件或文件夹写进去即可。并且github提供了大量的模板,我们可以直接复制下来,不需要从头开始写:传送门
.gitignore
的语法:
#
开头代表注释:# 注释
;- 文件夹名代表忽略该文件夹:
env
; - 文件名代表忽略该文件:
hugh.log
; - 可以指定文件夹或文件的路径,绝对或者相对路径都可以:
/home/hugh/env
; - 可以使用通配符
*
,比如忽略所有文件夹下的.pyc
文件:*.pyc
;
五、分支管理
分支可以理解为科幻电影中时间线,一个分支就是一条时间线,我们在A时间线上做的任何事都不会影响到B时间线中的任何事物。也就是说,我们在A分支上提交修改,不会影响到B分支中的内容,B原来啥样现在还是啥样。
之前我们来来回回执行提交、撤销等操作,都是在默认的master分支上,它是在初始化仓库时就创建好的。当然,我们可以自己创建、切换、删除分支,还可以合并分支。
-
查看分支:
git branch
如果分支有多个,那么前面带
*
号的,便是我们当前所在的分支。 -
创建分支:
git branch 分支名称
-
切换分支:
git checkout 分支名称
-
删除分支:
git branch -d 分支名称
注意:删除当前所在的分支会报错。
-
合并分支:
gir merge 要合并过来的分支
合并后,当前分支就会多了上面命令所指定分支的修改内容。
六、远程仓库
国内建议使用码云,因为访问速度要比GitHub快。不过GitHub毕竟是全球最大的代码托管服务平台,全球的大佬都会把自家开源的东西放在上面。所以,GitHub之后我们要用的比码云多。
6.1 远程仓库基础
注册登陆后,新建远程仓库:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-keDplfvq-1641692443488)(git的由来.assets/gitee新建仓库.jpeg)]
-
设置远程仓库的地址:
-
已有本地仓库:
如果已经有了本地仓库,就不要选初始化仓库、设置模板、选择分支模型,容易与本地的文件产生冲突。要是勾选了也没关系,冲突是可以解决的,我们会在后面学习。
git remote add 远程仓库的别名 https://gitee.com/xxxxxxxx/xxxxxxxxx.git # 注意是远程仓库的url不是浏览器地址栏的url
在新建完仓库后,码云会跳转到一个帮助页面,上面的命令可以在该页面上找到,包括远程仓库的URL。或者在
远程仓库的首页-->“克隆/下载”按钮-->“HTTPS”
找到远程仓库的URL。 -
没有本地仓库:
那就有两种解决办法:
-
新建本地仓库,然后执行上面那条命令(不推荐)。
-
克隆远程仓库到本地:
其实就是下载远程仓库到本地。
git clone https://gitee.com/xxxxxxxx/xxxxxxxxx.git # 还是之前那个url
-
-
-
查看远程仓库:
git remote
输出远程仓库的别名。
-
推送本地仓库到远程仓库:
在本地仓库做的任何修改,需要手动推送才能保存到远程仓库。
git push -u 远程仓库的别名 "分支的名称"
然后会git会提示我们输入码云账户的用户名和密码,输入即可。
-
拉取远程仓库到本地仓库:
与推送对应,他人提交到远程仓库的修改,需要我们手动拉去才能保存到本地仓库。
git pull
注意:为了避免冲突,建议在每次提交推送之前,先拉取一下!!!
6.2 使用SHH协议连接远程仓库
目前,我们连接远程仓库用的是HTTPS协议,它不需要额外的配置,但是每次都需要输入用户名和密码(有些IDE或编辑器可能会优化这一操作),十分麻烦。与之对应的是SSH协议,它需要事先配置一下,但好处是一劳永逸,以后都不用再输入用户名和密码了。
6.2.1 生成公钥
在终端中执行:
ssh-keygen -t ed25519 -C "xxxxx@xxxxx.com"
ed25519
是数字签名算法,最后面的字符串参数是我们的邮箱。
然后选择密钥的保存位置,默认是:/home/用户主目录/.ssh/id_ed25519
,可以直接回车,然后提示输入密码,直接忽视,按两次回车,完成!
6.2.2 添加公钥
在/home/用户主目录/.ssh/
目录下,id_ed25519文件是私钥,id_ed25519.pub就是我们要用到的公钥,使用cat命令查看并复制下来:
cat ~/.ssh/id_ed25519.pub
输出的内容就是公钥,将其复制下来。
点击右上角的头像,设置-->SSH公钥
,然后将复制的内容粘贴进去,标题默认会使用我们生成公钥时输入的邮箱地址。
现在,执行以下命令,测试公钥有没有添加成功:
ssh -T git@gitee.com
如果成功会输出:Hi Anonymous! You've successfully authenticated, but GITEE.COM does not provide shell access.
,否则就是失败了。
添加成功后,就可以使用SSH协议对仓库进行操作了。
PS:如果本地仓库之前使用HTTPS连接过远程仓库,建议在使用SSH协议之前,先用HTTPS全部推送到远程仓库,然后再克隆下来,这样可以免去一些配置问题。
七、冲突解决
假设有一个仓库有两条分支dev和master,且都用一个a.txt文件:
- 我们在dev分支上a.txt文件的第一行添加了:“ABC”;
- 而同事则在master分支上a.txt文件的第一行添加了:“BCD”。
然后我们进行分支合并,就会发现git在终端中提示我们出现了冲突,让我们解决完冲突再去提交合并后的内容。
而且,git还会用下面的格式,在a.txt标记出冲突的地方:
<<<<<<< HEAD
我们的代码
=======
同事的代码
>>>>>>> origin/master
我们可以通过提交历史,找到那位同事,和他商量着修改文件的内容以解决冲突。
八、标签管理
标签(tag)就是对某一个的特殊记号。通常在发布一个版本时,会在版本库中打一个标签,这样以后想要找这个版本,通过标签很容易就能找到,而不像提交ID那么难记。
-
创建标签:
git tag 标签
标签默认是打在最新一次提交上的。如果想对指定的某一次提交打标签,可以指定提交ID:
git tag 标签 提交ID
-
查看标签:
git tag
-
查看标签详细信息:
git show 标签
-
删除标签:
git tag -d 标签
-
推送指定标签:
git push origin 标签
-
推送全部标签:
git push origin --tags
-
删除远程标签:
git push origin :refs/tags/标签