一、git教程
(一) 安装和初始化仓库
- 请自行下载安装
初始化仓库
- 进入到目标目录(你想要用来存放代码的目录)
右键打开git bash,输入
git init
这时候你的当前目录就变成了一个代码仓库
- 可以使用git bash 运行相关命令执行诸如添加代码,提交代码,回滚等等
(二) git 仓库管理常用命令
git init
初始化 git 仓库
实操: 新建gitdemo文件夹,进入gitdemo,右键打开git bash,执行npm initrm .git -rf
删除仓库(或者直接删除隐藏文件夹.git)git add test.js
,把 test.js 添加到仓库
实操: 在gitdemo文件夹内,新建test.js文件,执行git add test.js
git add .
把所有文件添加到仓库git status
查看状态git commit -m"xxx"
提交
实操: git commit -m”新增test.js文件”git checkout .
放弃所有更改
实操: 修改test.js的内容,然后执行git checkout . 你会发现你所有的修改都没了git clean -fd
批量删除branch中新加的文件(untracked files)git log
查看历史提交记录
问题,如果在提交过程中出现以下界面
意思是说,你需要git 设置邮箱和用户名名,好让别人知道是谁提交的,只需要在git bash执行下面命令即可
git config --global user.email "xxx@xxx.com"
git config --global user.name "xxxx"
(三) git 仓库中文件状态
一、已跟踪文件和未跟踪文件
- 工作目录下面的所有文件都不外乎这两种状态:已跟踪或未跟踪。
- 从码云或者 github 中克隆下来的项目,所有文件都已跟踪的状态
- 已跟踪的文件是指本来就被纳入版本控制管理的文件,其他文件则是问跟踪(在 vscode 左侧可以清楚看到一个文件的状态),文件后面出现 U,表示未跟踪文件
- 新建一个文件比如,bbb.js,它的状态是未跟踪,当我们执行 git add bbb.js 时,这个文件就变成了已跟踪文件,已跟踪文件又有三种状态
二、已跟踪文件的三种状态
对于任何一个文件(已跟踪),在 Git 内都只有三种状态:
- 已修改(modified)已修改表示修改了某个文件,但还没有提交保存;
- 已暂存(staged)执行了
git add
操作,把已修改的文件放在下次提交时要保存的清单中。 - 已提交(committed),执行了
git commit
操作,该文件已经被安全地保存在本地数据库中了;
三、具体例子
新建=>添加=>提交
- 新建 test.js => 该文件出于未跟踪状态,vscode 中,该文件后面带一个 U
- 执行
git add test.js
,该文件变成了已暂存(staged)的状态 - 执行
git commit -m"添加test"
,此时文件变成了已提交(committed)状态
修改=>添加=>提交
- 修改 test.js 文件的内容,此时 test.js 文件是已修改(modified)状态
- 执行执行
git add test.js
,该文件变成了已暂存(staged)的状态
- 执行
git commit -m"添加test"
,此时文件变成了已提交(committed)状态
四、总结
- 新建的文件是未跟踪文件,后面带 M
- 提交过的文件被修改了,文件的状态是已修改的状态,后面带 M
- 执行了添加(git add)的文件变成了已暂存的状态
- 新增的文件后面带A
- 修改的文件后面带M
- 执行执行了提交(git commit)的文件状态是已提交
ps:2,3,4 文件状态都是跟踪文件的状态
(四) 版本的前进和回滚
- 查看git log版本信信息
如果我们要回退到aaa这次操作提交上来,我们只需要将id复制一下,然后执行下面命令即可
git reset --hard e55640863f0eb141e0857761f0268c61121c07ac
回到上一个版本
git reset --hard HEAD^ // 回到上上个版本用 git reset --hard HEAD^^
版本回退之后,如果想再回到现在,你只需要记住你要回到的id即可使用同样的命令回到现在
- 如果不记得版本id,还可以使用git reflog来查看你提交的历史记录,从中找到版本的id,再进行reset操作
练习
新建文件夹gitdemo2,执行,打开gitdemo2,右键打开git bash
git init
新建a.js文件,执行命令
git add .
git commit -m"aaa"
新建b.js文件,执行命令
git add .
git commit -m"bbb"
新建c.js文件,执行命令
git add .
git commit -m"ccc"
新建d.js文件,执行命令
git add .
git commit -m"ddd"
执行
git log
命令,出现以下界面
- 回到备注信息为 bbb的那一次提交
- 复制备注信息为 bbb 的版本号 b1703ad1bc0485f1b4a601ed968d3faccd74fa2f
- 执行
`git reset --hard b1703ad1bc0485f1b4a601ed968d3faccd74fa2f
- 其他的操作请看上面的知识点.
(五) 本地仓库和远程仓库
在前面的一到四章节,我们所有的操作都是在本地进行的,本文主要讲解本地仓库与远程仓库的相关知识点
代码托管网站
本地仓库和远程仓库常用命令
- 在码云网站注册一个账号(注意: 要用手机和密码注册),然后新建一个仓库,复制仓库地址
git clone xxx
(远程仓库地址) 把远程的仓库克隆到本地。例如:git clone https://gitee.com/huruqing/gitdemo.git@git
如果仓库地址是 https 开头,则需要输入用户名密码
git remote add origin xxx
关联远程仓库,例如:git remote add origin https://gitee.com/huruqing/gitdemo.git
git remote remove origin
断开与远程仓库的关联git remote -v
查看关联的远程仓库- 把本地仓库内容推送(同步)到远程仓库 git push origin xxx
- git push origin master 推送到远程仓库的主干
- git push origin dev 推送到远程仓库的 dev 分支
- git push origin master -u // -u 下次推送不用加分支名称,直接使用 git push 即可
- git push origin master -f // -f 强制推送,轻易不要使用
git pull
拉取代码,把远程仓库的代码同步到本地仓库,如果本地有代码未提交,需要先提交然后推送才能拉取代码
(六) 冲突处理
由于多人同时进行开发,有时候会同时修改一个文件,或者多分支开发,合并的时候就很容易引发冲突,下面是一个制造冲突和解决冲突的例子。
制造冲突
- 同学 A 新建码云仓库,同时添加同学 B 为开发者(其实一个人也可以制造冲突的)
- 同学 A 新建文件 main.js 并提交推送到远程仓库,同学 B 把仓库同步到本地,这时两位同学都有一个 main.js 的空文件
- 同学 A 在 main.js 的第一行添加”我是同学 A”,然后添加,提交并推送到远程仓库
同学 B 在 main.js 的第一行添加”我是同学 B”,
然后执行以下命令
git add .
git commit -m"修改main.js"
git push origin master
出现以下提示
意思是被拒绝了,要先执行 git pull 命令
- 执行
git pull
命令,同学 B 的界面上出现了以下情况
因为两位同学同时修改了同一行代码,所有 git 不知如何取舍(如果同学 a 修改了第一行,同学 b 修改了第二行,那么 git 会智能的合并),只好把合并代码这个事情交给开发者去处理,- 上图中<<<<<<< HEAD 到========的代码是 B 同学的代码,
- ======到>>>>>>> a248f68a5fcbcbe4cc887bee3dfc3cfd1cf7147b 的代码是同学 a 的代码,括号的 Incoming Change 的意思是从外面来的修改,a248f68a5fcbcbe4cc887bee3dfc3cfd1cf7147b 是仓库是冲突的版本号,你可以通过 git log 看到详细的信息.
- 你可以根据具体情况去合并代码,取 a 的代码或者取 b 的代码,或者 a 取一点,b 取一点,具体情况具体分析
- 当同学 A 和同学 B 都修改了同一个地方的代码,同学 A 推送了代码,同学 B 执行了
git add .
命令,但没有执行git commit
命令,就会出去下面的界面:
意思是要你先git commit
,然后再git pull
合并工具
- 使用 vscode 进行合并
- beyond compare
- 其他的合并工具
(七) 分支管理(废弃)
新创建的仓库,默认只有master分支,如果存在并行开发,则会拉取新的分支,最后再合并分支,有时候,也会使用两个分支,一个分支用来开发,一个分支用来部署项目,以下是分支管理的一些常用操作
- git checkout -b dev 创建并切换到dev分支
- git branch查看分支
- git checkout master 切换分支到master
- git merge dev -m”合并分支到主干” 合并分支dev到master
- 把主干代码同步到分支
- git checkout dev 切换到分支
- git merge master -m”合并主干到分支”
- 如果出现 fatal: refusing to merge unrelated histories,意思是这两个分支没有共同的祖先,需要这样去合并或者拉取
git merge dev —allow-unrelated-histories
- git branch -a 查看所有分支
- git fetch origin dev:dev 把远程分支dev同步到本地分支dev
- git branch -d dev 删除dev分支
- git push origin -d dev 删除远程的dev分支
(八) 可视化工具
- vscode集成了git,很多操作可以通过鼠标操作
- github desktop, 下载地址 https://desktop.github.com/
- sourcetree
- 小乌龟git 下载地址 https://gitforwindows.org/
(九) 给码云配置公钥
每次提交代码到码云的时候,都需要输入账户密码,真的很不方便,好在码云给我们提供了解决方案,只需要创建秘钥对,在码云上添加公钥就可以了,把私钥保存在本地即可,以下就是添加公钥的步骤。
生成秘钥对
- 打开 git bash
- 输入 ssh-keygen -t rsa -C “你的邮箱地址” 三次回车之后就可以生成密钥对
- 输入 cat ~/.ssh/id_rsa.pub 查看你的 public key(公钥),结果如下:
- 把途中从 ssh-ras(包含)到最后面的邮箱地址(包含)复制一下。
- 打开码云 -> 设置 -> SSH 公钥,就出现了下面的画面,把我们刚才复制的内容贴到提示区,最后点击左下角的确定即可。
- 输入 ssh -T git@gitee.com,系统会提示你输入 yes/no,输入 yes,如果出现:You’ve successfully authenticated, but GitHub does not provide shell access.
就表示成功了。
配置用户名密码
git config —global user.name “你的 gitee 账号”
git config —global user.email “你在 gitee 的邮箱地址”
设置完以上这些之后,再试试 git push 是否还需要提交账号密码
(十) .gitignore 忽略文件
有时候,有些文件或文件夹并不需要都推送到远程仓库,这时候,我们可以把它加入到忽略文件列表.具体做法:
- 在项目根目录添加.gitignore 文件
- 打开.gitignore 文件,添加你要忽略推送的文件,下面是一份忽略清单
.DS_Store
node_modules/
docs/.vuepress/dist/
(十一) 分支操作
- git checkout -b dev // 创建并切换到dev分支
- git checkout master // 切换到主干分支
- git branch // 查看分支
- git branch -a // 查看所有分支
- git fetch -a // 拉取所有分支, 拉取之后使用git branch -a才能看到别人新建的远程分支
- git push origin dev // 推送dev分支代码到远程仓库的dev分支
- git pull origin dev:dev // 拉取远程dev分支
- git merge dev -m”xxx” // 合并dev分支到主干分支(当前分支必须是master分支)
- git merge master -m”xxx” // 合并master分支到dev分支(当前分支是dev分支)
(十二) 为什么有时候git pull(git push) 无法更新代码
- 提示没权限, 如下图:
原因:
- 可能你真的没有权限
- 你的项目没有关联远程仓库
- 没有网络或者网络卡
- gitee网站的问题
- 出现以下提示:
原因:
在你提交之前, 已经有人先于你提交了, 你要先执行git pull把对方的代码更新下来, 再去执行git pull。
(十三) 本地已有项目存放到码云的步骤
- git init // 把本地项目变成git仓库
- 在码云上新建仓库
- 关联仓库 : git remote add origin 仓库地址
- git add .
- git commit -m”init”
- git push origin master -u