从 0 开始学 Git !
本篇出自一个使用
git
的小白,哈哈,也推荐给各位小白们,我们一起进步喽!大神们不要觉得太简单哦,小白们正在努力朝着你们跑来,一二三四,一二三四..... 好了,回归主题,写这篇文章的初衷是因为:自己最近发现对git
的掌握真的是太浅了,犹如蜻蜓点水,也借此机会从小白的角度来看git
,并对git
做一个初步探索性的了解,最要紧的是先满足我们平常的开发,文中如有错误,还望走过路过的大神们高抬贵手留言告知哦!谢谢🙏。
本篇文章先从实战的角度来进行讲解,涉及原理的问题,请待小白进阶后,再发文,敬请期待哦!😁
一、理解git
git
是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。——摘自百度百科
那么接下来我们就从几个方面来理解它,并分析git
在我们工作中提供了哪些便利:
1. 版本控制发展史:
u盘 -> 付费(CVS)->开源(SVN)-> 分布式(git)
2. 优点:
a. 方便:仓库统一管理,提交代码,拉取代码快速方便
b. 可追溯:每条提交都有记录,可追溯历史版本
c. 合并冲突:可合并冲突,保持开发人员的内容统一
d. 安全性较高:采用线上主仓库+本地仓库,安全性较高
3. svn
和 git
区别
svn: 集中式:只有一个中心服务器,只有一个最新版本
git: 分布式:每个客户端都是服务器,可以有很多个最新版本
下面画了两张草图,帮助理解:
-
首先是
svn
,相对来说操作路径较少,比较好理解: -
接下来是我们的
git
,这跟上图的svn
相比可操作路径就较多了:
4. 关于项目托管平台
市面上有很多存储的库,例如:码云、github
、gitlab
等
码云:既可以使用 git ,又可以使用 svn 来提交上传,通用性较强
github:属于开源代码库,是目前最火的开源项目托管平台,同时提供公共仓库和私有仓库,但如果使用私有仓库,是需要付费的。
gitlab:可以在上面创建私人的免费仓库,一般企业多选用
二、在仓库创建一个新项目
上面介绍了git
、github
,这一趴我们来在github
上创建一个项目试试。
此处跳过了注册 / 登录的步骤,各位小哥哥小姐姐自行注册呦。
1. 登录成功后,点击右上角你头像旁边的+
号,选择最后一项New project
创建一个新的项目。
2. 接下来去填写项目的信息。
3. 创建完成后会自动生成一个README.md
文件,这个文件主要是存放项目的描述信息,下载方式,运行信息,文件目录等等。
是不是感觉很简单,其实不难哦!😄
三、完成最简单的git
操作
我们现在已经有自己的仓库了,接下来试着模拟一下
clone
线上代码,本地开发,以及提交的一系列简单操作。
1. 查看 git
的版本
查看版本号
git --version
2. git help
: 查看帮助
这里有关于怎么从下载一下项目、保存、提交、合并分支、切换分支、查看历史记录等的
git
查看命令帮助操作。
git help
3. git clone
: 克隆代码
这个命令用于从远程将远程仓库的内容拉到本地,也是我们学习项目操作的比较常用的命令。
git clone <版本库的地址>
举例:
比如克隆iview
的版本库,(在这给我老东家的产品悄悄的打个广告!😄哈哈)
选择你认为合适的文件夹位置存放它,然后执行下面的命令:
git clone https://github.com/iview/iview.git
该命令会在本地主机生成一个文件夹,与远程主机的版本库同名。如果要指定不同的目录名,可以将目录名作为git clone
命令的第二个参数,如下:
git clone <版本库的地址> <本地你认为合适的库名>
下载完成。
4. git status
: 查看状态
养成一个好习惯,在每次提交保存代码或者要开始执行
git
操作时,先执行一次git status
,可以查看当前代码的状态。
当然执行完命令后有几种状态需要分别说明:
- 当前工作状态为无任何修改,无需提交
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean // (工作簿干净,无任何修改)
2. 当前工作簿有更改
add ‘XXXX’ (commit)
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit: // (有文件修改未暂存)
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: src/view/index.ux // (更改的文件,没暂存时的此行是红色)
no changes added to commit (use "git add" and/or "git commit -a")
3. 执行完暂存后
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: src/view/index.ux // (暂存后的此行是绿色)
4. 当添加一个新文件时
On branch master
Your branch is up to date with 'origin/master'.
Untracked files: (未被跟踪的文件)
(use "git add <file>..." to include in what will be committed)
src/view/test.txt
nothing added to commit but untracked files present (use "git add" to track)
5. 当新文件执行完暂存后
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: src/view/test.txt (新文件)
5. git add
:添加到暂存区
在上一讲中,我们也已经用过这个命令,那么这个命令是什么意思呢?打个比方:我们平常去超市,一般会推一辆购物车,然后把我们需要买的物品放到购物车中,然后在结账的时候,一起付款。那么这个命令就好比加入购物车的过程,开发完需求后,将要提交的代码提交到暂存区,然后才可以进行向上提交。
上面一直在说暂存,那么如何执行暂存呢?
就顺着这个往下来操作添加暂存:
有两种形式:
- 第一种是暂存指定文件 ,
add
后面的地址,直接从git status
的红色内容处复制来即可
git add src/view/test.txt
2. 第二种是暂存全部本地文件,将当前目录下(递归子目录)所有文件加入到暂存区,
add
后面跟一个 .
(点)
git add .
6. git commit
:提交到本地仓库
当我们把本地的更改提交到暂存后,接下来就要提交我们的暂存到本地仓库
git commit -m '提交内容的备注信息'
1 file changed,1 insertion(+) // 1个文件有修改 1个文件新添加
create mode 100644 src/view/test.txt
此时,我们已经把文件提交到了我们到本地仓库,然后再执行一遍git status
,查看一下状态,下面的内容告诉我们,我们有一个commit
,可以push
推到远程:
7. git push origin
:提交到远程仓库
在上面的流程里,我们已经把代码提交到里本地仓库,接下来就要把我们本地仓库推到远程仓库。
git push origin
接下来我们去看看github
仓库已经有我们刚刚push
的记录
强制将本地的修改覆盖远程仓库的版本,这个命令如果不是
git 老手,尽量不要使用! 不要使用!不用使用!
git push origin -f
写到这里我们似乎已经把一个简单的提交(提交到远程)表述完了,但我们都讲述都是一个项目一个人操作的流程,后续会分享关于多人合作配合的流程。
四、多人合作操作流程(必备技能)
当然我们不可能只是自己一个人在开发,更多的时候是多人协作,那大部分的
git
操作失误都是基于多人操作的,我们先分别阐述比较常用的命令,最后把整体流程走一遍。
1. 配置ssh
正常情况下,当我们没有配置SSH
的时候,每次git clone
下载代码时候都需要输入用户名和密码,如果我们已经正确设置了 SSH
密钥对并且将公钥添加到您使用的 Git
服务中,您在使用 git clone
命令时不需要再输入密码。
然而,有几种情况可能导致在使用 SSH 密钥对克隆时仍然需要密码:
-
- 您的公钥没有正确添加到
Git
服务中。请确保您的公钥已经正确上传到您的Git
服务中。在GitLab
、GitHub
、Bitbucket
等Git
托管服务中,您可以通过账户设置页面(或类似的设置页面)上传公钥。
- 您的公钥没有正确添加到
-
- 您的克隆
URL
中使用了HTTPS
协议而非SSH
协议。如果您使用的是HTTPS URL
,那么Git
仓库可能还是会要求您提供用户名和密码。要使用SSH
密钥对克隆Git
仓库,请使用SSH URL
(例如git@github.com:user/repo.git
),如下图。
- 您的克隆
-
- 在使用了
SSH
密钥对后,有时仍需要输入密码是因为您的SSH
密钥对受到了文件权限限制。请确保您的SSH
密钥对确切地命名为id_rsa
和id_rsa.pub
,并且权限为600
和644
。
- 在使用了
如果您已经检查过上述情况,并且仍然需要输入密码才能克隆 Git
仓库,请再次检查您的 SSH
密钥设定,以及是否使用了正确的协议和 URL
。
下面进入正题:
切换git
使用的用户名和生成密钥:
入职后公司会给每个人分发一个邮箱地址,一方面用于接收公司邮件,另一方面也用于我们代码提交的用户名。一般情况下我们是有两套用户名,一套是自己的
github
使用的用户名和密码,另一套是用公司邮箱生成的用户名和密码,如果在公司环境我们用公司的邮箱。
查看当前用户名:
git config --global user.name
查看绑定邮箱:
git config --global user.email
设置用户名:
git config --global user.name "zhangsan"
设置邮箱:
git config --global user.email "<13800138000@163.com>"
生成邮箱密钥:
ssh-keygen -t rsa -C "<13800138000@163.com>"
然后一路回车
ssh
分为公钥和私钥,私钥自己保存,公钥是生成后要复制出来放到公司gitlab
下的。
一般生成的密钥存放位置:
-
mac
: 当前用户名下的.ssh
文件中,以.
开头的是mac
的隐藏文件,如果你的隐藏文件都没有显示,那就使用Command + Shift + .
三个按键,即可查看当下文件夹中的隐藏文件。 -
windows
:我的电脑的C
盘->Users
-> 你的用户名 ->.ssh
文件
然后找到密钥所在位置:
打开公钥的文件夹,将它复制出来。
打开git
,点击个人头像 -> 找到settings
-> SSH and GPG keys
把密钥放进去:
上传后无需输入用户名和密码就可以直接上传代码了。
2. git remote
:对远程仓库的操作
我们在开发过程中针对不同情况会有不同数量的远程仓库,一般情况下会有两个,一个是自己的远程仓库,一个是公司项目的远程仓库,
自己的远程仓库 origin:用来存储自己暂时不需要提测和上线的代码;
公司的远程仓库 upstream:用来提交准备测试上线的代码;
查看所有的远程仓库
git remote -v
添加远程仓库
git remote add origin <fetch到自己的仓库的项目地址>
git remote add upstream <源项目地址>
下面是我已经添加完了两个仓库
关于为什么要添加远程仓库?我的理解是这样的,当我有两台电脑,一台在公司,一台在家,我在公司开发到一半,还不能提交到线上测试,我想回家后再继续开发,那就可以添加一个自己的远程分支,在公司将代码提交到远程,回家后拉取远程就可以同步代码啦。所以我们一般入职后,公司给开通
git
权限后,我们需要先把对应的项目fork
到自己名下,然后remote
添加一个自己的远程库。
3. git checkout
:切换分支
根据环境不同,需求不同,我们一般会有多个分支用来区分代码块
切换到其他分支
git checkout <分支名> => git checkout qa // 切换到qa 分支
直接拉取线上最新的代码,并创建一个新的分支,例如你线上的分支叫production
:
git checkout production // 先切到production分支
git fetch --all // 更新所有的分支
git checkout -b <新分支名> => git checkout -b feature-xxx //创建完成后会自动切换到新分支
4. git fetch
:拉取远程分支
同步远程代码
1. 下面命令将某个远程主机的更新,全部取回本地
git fetch <远程主机名>
eg:
拉取
upstream
全部的更新到对应分支,qa->qa
production->production
git fetch upstream
2. 取回特定分支的更新
git fetch <远程主机名> <分支名>
eg:
拉取到
upstream
主机的production
分支
git fetch upstream production
5. git merge
:合并指定分支到当前分支
将指定分支的代码合并到当前分支
git merge [新代码的分支,也就是指定分支]
eg:
假设我们现在位置是
qa
分支,需要将feature-classDetail
分支开发的新代码合并到production
分支
git checkout production
git merge feature-classDetail
6. git merge --abort
:放弃解决冲突,撤销当前的 merge
操作
多人操作时避免不了修改同一个文件,同一段代码的时候,那这时就会产生代码冲突。对于出现冲突,我们的第一反应:当然是去解决冲突了,但有时
merge
操作后,才发现自己改错了代码,或者想撤销合并等操作。此命令只适用于merge
操作执行后,代码冲突的后的取消merge
操作,并不能取消正常的无冲突的merge
。
下面我们就来模拟一个冲突:
分支A:
分支B:
此时将分支A
合并至 qa 分支
:
git checkout qa
git fetch upstram && git reset --hard upstream/qa
git merge A
接下来我们再将
分支B
合并至qa分支
,如上同样的操作,我们看一下冲突页面:
此时我们可以使用我们撤销
merge
的命令(abort
意为中止,也就是取消):
git merge --abort
取消
merge
后,页面还原为合并分支A
的内容
7. git pull
:同步远程代码并合并
事实上,
git pull
这个指令的内部实现就是把远程仓库使用git fetch
取下来以后再进行merge
,但前提是需要先将本地的代码暂存起来,不然 如果远程也改了相同的文件位置,会被远程的代码覆盖。(我们公司是禁止使用这个命令,明令要求大家必须分步git fetch +git merge
有选择的合并)
假如你已经在本地更改了一些你的工作区,前提是你知道将要pull
的内容不会覆盖你的工作区的内容,否则不要使用 pull
这个命令,老老实实用git fetch
和 git merge
来同步和合并。
git pull <远程仓库名> <远程分支名>:<本地分支名>
它们是等价的:
git pull === git fetch + git merge
eg:
git pull
等同于先执行
fetch
,然后将对应的远程分支merge
合并到当前分支
eg:
git pull origin
等同于先执行
fetch
,然后将对应的远程仓库origin
的分支merge
合并到当前分支
8. git reset
:丢弃修改
重置工作区,丢弃已有的修改,丢弃暂存区和工作区对所有文件对修改
git reset --hard
丢弃本地的所有修改,并将对标到某个主机的某个分支
git reset --hard <主机>/<分支>
eg:
丢弃本地所有更改,并将代码更新为
upstream
的qa
分支
git reset --hard upstream/qa
9. git stash
:将所有未提交的修改保存至堆栈中,用于后续恢复当前工作区内容
这个是我用的比较多的命令,在我们的工作中,大部分是需要快速迭代,而且还会有一个迭代有多个不相干的需求,再加上需要等待后端同学。那么在迭代开始时,我一般倾向于将多个需求分多个分支来开发,这样保证上线互相不影响。
上面👆 是背景,下面👇 是使用场景:
那么多个分支是如何保存我们的代码呢?那就用到了我们
git
的存储功能,例如我现在有A、B、C
三个分支,我先开发了A
需求,但接口还没出,这时我们可以将A
的代码存一下,然后继续再开发B
的需求....
a. 基础使用
当我们只有一个小改动,只是暂时存储一下时,我们可以直接用下面的命令,当然它不只是可以存一次,可以存多次
git stash
b. 查看保存的列表
上面我们将我们暂时不提交的内容暂时存储了起来,使用下面命令查看保存的列表
git stash list
c. 查看list
中具体的修改
上面我们已经能看到我们存的
list
列表了,那么具体修改的内容是啥呢,这时我们需要使用git stash show stash@{X}
命令来查看,其中X
表示列表的序号。
git show stash@{0}
d. 应用到当前工作区
上面我们已经知道哪个是自己修改的版本,此时我们要将它还原到工作区,
git apply stash@{X}
命令来查看,X
同样还是我们看到列表的序号。
git apply stash@{0}
e. 自定义备注名称
上面的操作中,我们使用的都是默认存储,要还原时,还需要查看一下修改内容,未免有点麻烦,那么我们这次就给每个保存的版本添加一个备注,这样我们还原时就可以直接选择对应的版本了。
git stash save '新增e'
此时我们再看一下我们的 list
:
上面的
list
中,最后一个是我们最新添加的版本,使用的就是我们自定义的备注名称。
五、其他的的功能 / 命令
我们平常用的较少,但比较实用的命令(或者可以说遇到问题时会用到的命令)
1. 查看git
历史提交记录
有时我们想恢复上一个提交,回滚代码时,一般会先查看历史提交记录,然后找到对应的编号,进行回滚
git log
查看的历史的commit
提交,不能查看已经删除的commit
记录
git log
git reflow
可以查看所有分支的所有操作记录(包括已经被删除的commit
记录和reset
的操作)
git reflog
2. 修改commit
备注信息
git commit --amend
按
I
健进入编辑,按esc
保存编辑,:wq
退出并编辑状态
编辑完退出后即可看到已经修改成功:
查看历史提交列表:
3. 撤销最近一次的 commit
提交,常用于代码回退
有时刚刚提交了
commit
后,发现自己提交错了,想要撤销提交,还原到上次的提交,那就用到了下面的命令
这个是提交前的commit
记录:
然后修改一些东西,提交上去,这是更新后的commit
记录:
然后执行下面的命令,撤销最新的 commit
:
git reset --hard HEAD^
执行后看我们更新后的 commit
记录:
4. 代码回退到指定版本
如果想回退的不是最新的一个,是历史的某个
commit
版本那就把commit
编号记录下来:
git reset --hard d9dc2c6ff6a3f4eef3f11bd83e259fcf19a36f69
下面就是回退后的commit
记录:
5. 删除指定的 commit
一定要认清风险,谨慎删除
git rebase -i HEAD~3 // HEAD后面的数字代表往回数几条,HEAD~3:最近3条的commit
键盘输入i
进入编辑页面,将要删除的commit
前面的pick
改成 drop
,然后esc
退出编辑,:wq
退出修改界面。
修改成功后会提示:
Successfully rebased and updated refs/heads/xxxxxx.
git log
再次查看就已经没有此commit
记录了。
6. 撤销之前的某次提交
场景:如果我们想撤销之前的某一个提交,但是又想保留该目标版本后面的版本。
举个例子,现在库里面有三个文件:READ.md、text.txt、text2.txt
最近的两个提交分别是:add text.txt
(即新增了文件text.txt
)、add text2.txt
(新增了文件text2.txt
)。这个时候我们不需要text.txt
这个文件了,那就是说不想要add text.txt
那个版本的操作,那可以通过反做add text.txt
这个版本来实现。
也可以通过github
网站图形化界面查看版本号:
反做,使用git revert -n 版本号
命令:
git revert -n 8b89621019c9adc6fc4d242cd41daeb13aeb9861
注意:这里可能会出现冲突,那么需要手动修改冲突的文件。再进行提交。
git add .
git commit -m "revert add text.txt"
此时可以用git log
查看本地的版本信息,可见多生成了一个新的版本,该版本反做了add text.txt
版本,但是保留了add text2.txt
版本:
推到远程库:
git push upstream
查看github上
显示的远程库版本信息:
此时查看仓库的文件,剩下两个:READ.md text2.txt
最后来分享一下我们公司的gitflow
提交流程,欢迎讨论。
后面会持续更新,请收藏关注哦!!
转载自:https://juejin.cn/post/6844904202070654989