Git基本理念
首先,我们需要知道的是Git是一个版本管理工具,它为我们提供了大量实用的命令,帮助我们实现有效的多人协作开发。
工作流程
Git的工作流程一般大体如下:
- 克隆Git资源作为我们自己的工作目录;
- 在克隆的资源上添加或修改文件;
- 如果其他人修改了克隆的资源,我们可以及时更新资源;
- 在提交之前查看修改;
- 提交修改;
- 在修改完成后,如果发现错误,可以撤回提交并且再次修改并提交。
几个基本概念
- 工作区:就是我们电脑里面能看到的目录。
- 暂存区(stage,index),一般存放在.git目录下的index文件,有时候也把暂存区称作索引(index)。
- 版本库(仓库,repository):工作区有一个隐藏目录.git,它就是Git版本库。
Git基本操作
git init 创建本地仓库
git add . 将文件添加到暂存区
git commit 将暂存区的内容添加到仓库中
git log 查看版本更改的历史记录
git reset 版本回退
Git提交文件操作
如何提交提定文件更改到暂存区,如何提交特定文件夹更改到暂存区,如何提交全部文件更改到暂存区?
git add readme.md 提交文件到暂存区
git add readme.md test.txt 提交多个文件到暂存区
Git状态的掌握
使用git status可以时刻掌握仓库当前的状态,
使用git diff可以查看difference,即两者的区别
Git版本的回退与恢复
我们在开发项目时,少不了多次提交代码,这样也就有了许多个不同的版本了。但是我们有时候就需要回到特定的版本中处理一些代码。对此,我们首先要用到命令git log
显示所有的版本信息,可以看见此时git显示了最近至远的各种版本,里面都包含了每一个版本的具体信息。在Git中,HEAD表示当前版本,上一个版本就是HEAD^,上上个就是HEAD^^,类推,往上50个就写作HEAD~50。
例如,回退到上一个版本,可使用如下命令:git reset --hard HEAD^
那如果回退了之后,又想回到原来的新版本呢?别急,有如下命令:git reflog
它将显示我们的每一次命令,然后我们就可以看到原来版本的commit id(假设就是14331a),再使用命令git reset --hard 14331a
就可以回来辣。
撤销修改
对文件的撤销修改,需用到命令:git checkout -- 文件名
将文件在工作区的修改全部撤销(丢弃工作区的修改),即让该文件回到最近一次git commit或者git add时的状态。
这种情况有两种:
- 文件修改后,还没有提交到暂存区;
- 文件提交到了暂存区,但是又作了修改,现在撤销修改就是回到添加到暂存区后的状态。
若文件已经提交到暂存区了呢?那就需要这个命令了:git reset HEAD <file>
它可以把暂存区的修改撤销掉,重新放回工作区
也就是说,git reset命令既可以将暂存区的修改回退到工作区,也可以回退版本。
文件的删除
只从工作区删除了文件,工作区就会和版本库不太一致了。如果要彻底删除文件(以test.txt为例),执行如下命令:git rm test.txt
git commit -m"remove test.txt"
即可实现test.txt的完全删除
如果只是删除错了文件,就使用git checkout -- test.txt
这是因为版本库里面还存在这个文件,用版本库中的版本替换工作区中的版本即可(丢弃工作区的删除)。
远程仓库
在本地仓库下运行命令,可以将本地仓库与远程仓库关联起来:git remote add origin git@github.com:账户名...
在创建了远程仓库,并与本地仓库关联之后,就可以将本地仓库的所有内容全部推送到全程仓库中:git push -u origin master
第一次推送时,加上了-u参数,本地的master分支还会和远程的master分支关联起来,简化以后的推送或者拉取命令。
从远程仓库克隆
准备好远程库后,使用git clone可以克隆一个本地
Git分支管理
本地分支管理
git branch 创建分支命令
git branch -X 创建分支,-X为分支名
git checkout -X 切换分支命令,切换到-X分支
git checkout -b branchname 创建分支并立即切换过去
git switch branchname 切换至已有的分支
git switch -c dev 创建并切换至已有分支
git branch -d branchname 删除本地分支
分支合并
将任何分支合并到当前分支中:git merge 分支合并
- 一种简单的情况,是将master分支与dev分支直接合并,假设我们已经在master分支上了:
git merge dev
便可直接将master和dev合并了
删除分支
git branch -d <branchname>
如果要丢弃一个没有被合并过的分支,可以通过git branch -D <branchname>
来强行删除。
解决冲突
当合并的两个分支产生冲突(一般是文件内容不同)时,必须首先解决冲突。只有解决完冲突后,才可以再提交,此时合并完成。
而解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
Bug分支
有时候我们在开发中遇见了bug,就需要另开一个分支去修复bug,但是这时候,可能我们手边正在开发的工作还没有提交,因此,就需要先将当前的工作存储下来。git stash
该命令可以将当前工作现场“存储”起来,等以后恢复现场后继续工作。
接下来,就可以继续新建分支修复bug了…
修复bug完成后,也需要合并分支,当整个工作结束后,我们需要将工作现场还原。用到如下命令:git stash list
恢复工作现场有两种命令:git stash apply 恢复工作现场,同时不删除stash
git stash pop 恢复工作现场,同时删除stash
此时master分支已经修复了bug,但是其他的开发分支,比如dev中bug仍然存在。能不能直接将本次针对修复bug的提交拿到开发分支dev上呢?
命令git cherry-pick 提交id
可以实现复制一个特定的提交到当前分支。
多人协作
远程库
当我们从远程库克隆时,实际上Git就自动把本地的master分支和远程的master分支对应起来了,且远程仓库的默认名称是origin。
查看远程库信息:git remote
git remote -v
在默认情况下,origin指向的就是用户在github上的远程仓库repository。
与远程库建立关联
与github上的仓库关联:git remote add origin 地址
与gitee上的仓库关联:git remote set-url --add origin 地址
进行如上的操作之后,本地的.git\config文件下就会显示关联的远程仓库的信息。
推送分支
即将该分支上的所有本地提交推送到远程库。推送时,需要指定本地分支,这样Git就会把该分支推送到远程库对应的远程分支上。git push origin <branchname>
将本地分支branchname推送到远程仓库origin对应的远程分支上。
常见的四种分支:
- master分支是主分支,因此要时刻与远程同步;
- dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
- bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
- feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
多人抓取分支
当我们提交分支到远程分支时,首先需要确保自己的代码是最新状态。因此需要git pull拉取远程代码。
常见的情况是,首先git pull把最新的提交从origin/dev抓下来,然后再本地合并,并解决冲突,再推送。
而为了顺利git pull,首先需要指定本地dev分支和远程origin/dev分支的链接:git branch --set-upstream-to=origin/dev dev
接着再pull:git pull
接下来就是手动解决冲突的时间了。
解决完冲突后,就需要推送了,使用命令git pull origin <branchname>
即可推送成功。
fork
即常说的克隆。在github上随便逛的时候,瞧中了一个项目,拿到它的地址在本地git clone一下,它就被扒取到了。
Codereview
中文可以理解为代码评审,旨在保证代码的规范性,更好地促进团队的开发工作。
- When?每一次代码合并(Pull Request)的时候,就是codereview的最佳时机。另外,每一次提交合并请求都需要确保代码的粒度,也就是说,不要一次性提交大量的代码,而是要修改一次提交一次、实现了一个功能模块提交一次。
- How?选用一些代码托管平台,比如github、gitlab等等,借助上面的代码codereview工具也可以进行评审。
- What?对代码的规范性、完整性、正确性、健壮性、可扩展性等方面进行评审。
PR
即pull request。请求合并代码。
我们在fork一个项目,并在本地做好修改、commit之后,想要将自己的这部分贡献推送给原项目,怎么办?
首先需要做一下同步,git rebase或者git merge拉取其他人做出的最新改动,然后在github上创建pull request合并请求,等待维护人管理通过即可。