git使用
基础篇
github术语
Repository:简称Repo,可以理解为“仓库”,我们的项目就存放在仓库之中。也就是说,如果我们想要建立项目,就得先建立仓库;有多个项目,就建立多个仓库。
Issues:可以理解为“问题”,举一个简单的例子,如果我们开源一个项目,如果别人看了我们的项目,并且发现了bug,或者感觉那个地方有待改进,他就可以给我们提出Issue,等我们把Issues解决之后,就可以把这些Issues关闭;反之,我们也可以给他人提出Issue。
Star:可以理解为“点赞”,当我们感觉某一个项目做的比较好之后,就可以为这个项目点赞,而且我们点赞过的项目,都会保存到我们的Star之中,方便我们随时查看。在 GitHub 之中,如果一个项目的点星数能够超百,那么说明这个项目已经很不错了。
Fork:可以理解为“拉分支”,如果我们对某一个项目比较感兴趣,并且想在此基础之上开发新的功能,这时我们就可以Fork这个项目,这表示复制一个完成相同的项目到我们的 GitHub 账号之中,而且独立于原项目。之后,我们就可以在自己复制的项目中进行开发了。
Pull Request:可以理解为“提交请求”,此功能是建立在Fork之上的,如果我们Fork了一个项目,对其进行了修改,而且感觉修改的还不错,我们就可以对原项目的拥有者提出一个Pull请求,等其对我们的请求审核,并且通过审核之后,就可以把我们修改过的内容合并到原项目之中,这时我们就成了该项目的贡献者。
Merge:可以理解为“合并”,如果别人Fork了我们的项目,对其进行了修改,并且提出了Pull请求,这时我们就可以对这个Pull请求进行审核。如果这个Pull请求的内容满足我们的要求,并且跟我们原有的项目没有冲突的话,就可以将其合并到我们的项目之中。当然,是否进行合并,由我们决定。
Watch:可以理解为“观察”,如果我们Watch了一个项目,之后,如果这个项目有了任何更新,我们都会在第一时候收到该项目的更新通知。
Gist:如果我们没有项目可以开源或者只是单纯的想分享一些代码片段的话,我们就可以选择Gist。不过说心里话,如果不翻墙的话,Gist并不好用。
配置用户名和邮箱
使用git前配置用户名和邮箱,这样才能够识别出来是谁提交的内容
1 | git config --global user.name "keqiudi" #配置用户名 |
创建仓库
方式一:git init
先找到找到合适位置的目录,进入该仓库
1 | git init #初始化该仓库 |
方式二:git clone
先在github上常见仓库,再使用git clone
1 | git clone https://github.com/keqiudi/keqiudi.github.io |
工作区域和文件状态
git本地数据管理分为三个区域:
- 工作区:英文名working directory,即资源管理器中看到的文件夹,实际操作的目录
- 暂存区:英文名staging area/index,用于保存即将提交到git仓库的修改内容,git版本控制中重要区域
- 本地仓库:英文local repository,通过git init创建的本地仓库,包含完整的项目历史和源数据
流程:
- 修改工作区文件后,需要将他们添加到暂存区
- 再将暂存区中的修改提交到本地仓库中
git文件状态分为四种:
-
未跟踪:新创建没有被git管理起来的文件
-
未修改:已经被git管理的文件但文件内容没有被修改过
-
已修改:已经被git管理的文件但文件内容被修改过,没有添加到暂存区的文件
-
已暂存:已经被git管理的文件但文件内容被修改过,已经添加到暂存区的文件
添加提交文件
- 查看当前仓库状态,查看分支、文件等等
1 | git status |
- 添加文件到暂存区
1 | git add fileName |
- 提交文件
1 | git commit -m "提交信息" |
- 查看提交记录
1 | git log |
回退版本
git reset命令用于回退版本,可以退回到之前某一个提交状态,有三种模式
- 表示回退到某一个版本,并且保留工作区和暂存区的所有修改内容,即所有工作区和暂存区在回退版本之后的修改都会保留
1 | git reset --soft 版本ID |
- 表示回退到某一个版本,并且丢弃工作区和暂存区的所有修改内容,即所有在工作区和暂存区在回退版本之后的修改都不会保留,完全回到当时版本的工作区和暂存区
1 | git reset --hard 版本ID |
- 表示回退到某一个版本,并且只保留工作区修改的内容,丢弃暂存区修改的内容,即暂存区在回退版本之后的修改都不会保留,而工作区会保留到最新版本的工作区内容
1 | git reset --mixed 版本ID |
一般只使用soft和mixed,谨慎使用hard,但若误操作也没关系,git中的命令是可以回溯的,当我们误操作的时候只需要使用git reflog命令查看操作历史记录,找到误操作之前的版本号,再使用git reset回退到这个版本就可以了
查看文件差异
git diff命令可以用于查看文件在工作区、暂存区、本地仓库之间的差异,也可以查看不同版本,不同分支中文件的差异。
1 | 红色代表删除的内容,绿色是添加的内容 |
HEAD是Git中的一个非常重要的概念,指向分支最新提交结点,而HEAD~/HEAD^可以表示上一个版本,通常用于比较当前版本和上一个版本区别。我们还可以在HEAD波浪线后加上数字代表提交之前的几个版本
删除文件
从版本库中删除文件一共有两种方法:
- 直接删除文件后提交
1 | rm file1.txt # 只删除了工作区文件,未更新暂存区文件 |
- 使用git rm删除(更简单)
1 | git rm file2.txt |
.gitignore文件
在git中有个特殊文件,叫忽略文件,可以忽略掉一些不应该加入版本库中的文件,可以让我们的版本库体积更小,更干净
一般来说遵循下面的原则
- 系统或者软件自动生成的文件
- 编译产生的中间文件和结果文件
- 运行时产生的日志文件、缓存文件、临时文件
- 涉及身份、密码、口令、密钥等敏感信息文件
先创建.gitignore文件,在通过vim对.gitignore文件进行设置过滤文件
1 | touch .gitignore |
假设下方为.gitignore文件内容
1 | access.log #代表忽略access.log文件 |
.gitignore文件还可以忽略文件夹内容,注意文件夹格式是以/结尾,才能正常忽略文件夹
1 | *.log # 代表忽略所有.log文件 |
注意.gitignore文件生效有一个前提,就是这个文件不能先添加到版本库中,若已经添加到版本库中.gitignore文件将不会生效
.gitignore文件的匹配规则:
从上到下逐行匹配,每行表示一个忽略模式
Git - gitignore 文档 (git-scm.com)
1 | 1.空行或者以#开头的行会被git忽略。一般空行用于可读性分隔,#一般用于注释 |
1 | 忽略所有的.a文件 |
github上提供了各种常用语言的忽略文件的模板,在新建仓库时可以直接使用,也可以根据需要自己修改
以下为链接:
GitHub - github/gitignore: A collection of useful .gitignore templates
SSH绑定git与github
我们就一起完成 Git 和 GitHub 的绑定,体验通过 Git 向 GitHub 提交代码的能力。不过在这之前,我们需要先了解 SSh(安全外壳协议),因为在 GitHub 上,一般都是通过 SSH 来授权的,而且大多数 Git 服务器也会选择使用 SSH 公钥来进行授权,所以想要向 GitHub 提交代码,首先就得在 GitHub 上添加 SSH key配置。
生成SSH key
-
输入ssh 查看本机是否安装ssh
-
输入ssh-keygen -t rsa -C “your_email”
- 表示我们指定 RSA 算法生成密钥,然后敲三次回车键,期间不需要输入密码,之后就就会生成两个文件,分别为id_rsa和id_rsa.pub,即密钥id_rsa和公钥id_rsa.pub. 对于这两个文件,其都为隐藏文件,默认生成在以下目录:
- Linux 系统:~/.ssh
- Mac 系统:~/.ssh
- Windows 系统:C:\Documents and Settings\username\.ssh
- Windows 10 ThinkPad:C:\Users\think.ssh
密钥和公钥生成之后,我们要做的事情就是把公钥id_rsa.pub的内容添加到 GitHub,这样我们本地的密钥id_rsa和 GitHub 上的公钥id_rsa.pub才可以进行匹配,授权成功后,就可以向 GitHub 提交代码啦!
- 添加 SSH key
- 进入github中的settings,再点击SSH and GPG Keys进入此子界面,然后点击New SSH key按钮:
- 将公钥id_rsa.pub的内容粘贴到Key处的位置(Titles的内容不填写也没事),然后点击Add SSH key 即可。
- 验证绑定是否成功
在 Git Bash 中输入ssh -T git@github.com进行测试:
结果即为Git 与 GitHub 绑定成功的标志。
通过git将代码提交到github
pull与push
push:该单词直译过来就是“推”的意思,如果我们本地的代码有了更新,为了保持本地与远程的代码同步,我们就需要把本地的代码推到远程的仓库,代码示例:
1 | git push <远程主机名> <本地分支名>:<远程分支名> |
pull:该单词直译过来就是“拉”的意思,如果我们远程仓库的代码有了更新,同样为了保持本地与远程的代码同步,我们就需要把远程的代码拉到本地,代码示例:
1 | git pull <远程仓库名> <远程分支名>:<本地分支名> |
pull request它表示:如果我们fork了别人的项目(或者说代码),并对其进行了修改,想要把我们的代码合并到原始项目(或者说原始代码)中,我们就需要提交一个pull request,让原作者把我们的代码拉到 ta 的项目中,至少对于 ta 来说,我们都是属于远程端的。
一般情况下,我们在push操作之前都会先进行pull操作,这样不容易造成冲突。
提交代码
对于向远处仓库(GitHub)提交代码分为两种情况:
第一种:
- 本地没有 Git 仓库,这时我们就可以直接将远程仓库clone到本地。通过clone命令创建的本地仓库,其本身就是一个 Git 仓库了,不用我们再进行init初始化操作啦,而且自动关联远程仓库。我们只需要在这个仓库进行修改或者添加等操作,然后commit即可。
1 | git clone https://github.com/guobinhit/mybatis-tutorial.git (仓库链接) |
-
将需要提交的文件复制到该仓库中
-
使用git status、git add、git commit -m " "、git log、git status
-
将本地仓库的内容push到远程仓库,输入git push origin master
在第一次向远程仓库提交代码的时候,需要输入账号及密码进行验证,验证成功后即可。
第二种
有本地Git 仓库,并且我们已经进行了多次commit操作。
- 进入该仓库,git init初始化操作:
- 命令,关联远程仓库(在此,默认大家都知道如何获取远程仓库的地址),其中origin为远程仓库的名字:
1 | git remote add origin https://github.com/guobinhit/springmvc-tutorial.git |
- 输入git pull origin master命令,同步远程仓库和本地仓库:
- 再回到本地springmvc-tutorial仓库,看看我们是否已经把远程仓库的内容同步到了本地:
- 输入git add和git commit命令,将文件添加并提交到springmvc-tutorial仓库:
- git push origin master命令,将本地仓库修改(或者添加)的内容提交到远程仓库:
在这个例子中,我们将远程仓库命名为origin,本地仓库名为springmvc-tutorial,其实两者的名字咱们可以随意取,一般来说,我们习惯性将远程仓库命名为origin,不过在需要关联多个远程仓库的时候,就需要我们再取别的名字啦!
在我们向远程仓库提交代码的时候,一定要先进行pull操作,再进行push操作,防止本地仓库与远程仓库不同步导致冲突的问题,尤其是第二种提交代码的情况,很容易就出现问题。
GUI工具
常用的
- github Desktop
- GitKraken
- Sourcetree
分支简介和基本操作
我们可以将分支branch看做代码库中的不同版本,可以独立存在并且有自己的提交记录,分支非常适合团队协作和开发管理,比如多个程序员可以在自己的分支上进行开发工作,我们可以在分支上建立一个新问题的开发或者建立一个问题修复的分支来处理一些bug和缺陷,这样就可以让主线代码仓库处于稳定可用状态。而不会影响到其他功能的开发和测试,能够提高团队开发效率
- 创建新分支
1 | git branch <新分支名> |
- 删除分支
1 | git branch -d <已经完成合并的分支> |
- 查看有哪些分支
1 | git branch |
- 切换到指定分支/恢复文件或目录状态
1 | git checkout <切换的分支名> |
- 合并分支
1 | git merge <需要合并的分支名> |
- 查看分支图
1 | git log --graph --oneline --decorate --all |
解决分支合并冲突
一般情况,**如果两个分支的修改内容没有冲突,git会自动完成合并。**但如果两个分支修改同一文件的同一行代码,那么git就不知道该保留哪个,所以需要我们手动来解决冲突。
当我们和并分支,输入git merge之后,提示存在合并冲突之后,会自动进入处理合并冲突状态,此时如果想取消该次合并只需要输入
1 | git merge --abort |
如果想继续合并,现在需要解决冲突
-
- 我们先输入git status或git diff 来查看冲突位置
1 | git diff |
-
- 此时我们只需要再进入冲突的文件删除不想要的地方和保留想要的地方即可,同时把提示内容一并删除(+和<和==等)
-
- 再git add . 和git commit 即可
切记在每个分支修改内容后一定要记得add和commit,否则就会出现修改一同带入到切换到的分支的后果,导致两个分支中同一个文件内容出现同步修改
回退和rebase
我们在删除了分支之后可以用命令将已经删除了的分支恢复到指定版本,命令如下
1 | git checkout -b <恢复的分支名称> <恢复版本的提交ID> |
rebase叫做"变基",会将当前所处分支变基到目标分支上,会将两分支共同祖先之后的内容变基到目标分支上,类似嫁接移植,故在不同分支用rebase会产生不同的变基结果,最终都会是一条分支
1 | git rebase <目标分支> |
1 | 以下是一个示例 |
Merge
优点:不会破坏原来分支的提交历史,方便回溯和查看
缺点:会产生额外提交结点,分支图较复杂
Rebase
优点:不会新增额外提交记录(合并),形成线性历史,比较直观和干净;
缺点:会改变提交历史,改变了当前分支branch out的节点,应当避免在共享分支中使用,一般不会和共同开发的分支中使用,当确定只有自己在该分支开发时且希望提交历史更加清晰明了则推荐使用。
标签
tag用于在开发阶段创建标签,某个阶段完成了创建一个版本,在开发中可以使用tag来指定软件的一个重要时期,比如版本号更新的时候可以创建一个v1.0,这样回顾的时候比较简单
- 查看tag
1 | git tag |
- 创建tag
1 | git tag version 1.0 #也可以 git tag 1.0 |
- 删除tag
1 | git tag -d <标签名字> |
分支命名和管理
分支命名:
- 推荐使用带有意义的描述性名称来命名分支
- 版本发布分支/tag示例:v1.0.0
- 功能分支示例:feature-login-page
- 修复分支示例:hotfix-#issueid-desc
分支管理:
- 定期合并已经成功验证的分支,及时删除已经合并的分支
- 保持合适的分支数量
- 为分支设置合适的管理权限