玩转Git
前言
当我们开始系统的编程时版本控制是不可或缺的。思考一下,当你正在为你的代码添加某项功能的时候,你发现这个功能难以实现不想要了,你会怎么做?疯狂删除之前打的代码吗?当你和别人一起合作编写代码的时候,你们的代码如何合并到一起?手动合并吗?这些问题都可以用版本控制软件解决,而Git是我们最常用的软件版本控制软件。
本文将通过四个场景来熟悉git的使用
参考文献https://mp.weixin.qq.com/s/Km5KuXPETvG0wCGHrvj9Vg
Git入门
Git安装
这里直接去git官网下载就好了安装完后,你将有3个可用的程序
Git的一些常用名词
| 名称 | 含义 |
|---|---|
| HEAD | 使用git你将会为你的代码产生很多的版本,而HEAD就是当前所在版本的指针 |
| master | 创建一个git仓库后默认生成的主分支,不知到以后会不会因为“政治正确”而改用main |
| line diff | 是形成增量补丁的技术方法,即一个文件按行对比(line diff)将差异的部分制作成一个增量补丁 |
| commit | 是存储到仓库里的一个版本,是整个项目范围内的一个或多个文件的增量补丁合并起来,形成项目的增量补丁,是一次提交记录。每个提交(commit)都生成一个唯一的commit ID |
| branch | 就是分支,是按时间线依次排列的一组提交记录(commit),理论上可以通过当前branch上最初的提交(commit)依次打补丁直到HEAD得到当前工作区里的源代码 |
| tag | 标签就是某次提交(commit)的commit ID的别名 |
图中每一个节点就是一个commit版本,通过commit ID区分,HEAD指向的节点就是当前所在的版本。每一条先代表一个分支,黑色的是master分支
设置用户名和邮件
git要求提交代码时带有提交人的一些信息比如昵称和邮件,我们就先设置一个全局的用户名和邮件,当然你也可以先不设置但是当你第一次提交代码时git也会提示你要设置用户名和邮箱。
打开git bash或直接使用命令行,我们使用以下代码进行设置
git config --global user.name "你们的昵称"
git config --global user.email 你的邮件
你也可以通过git gui也就是图形界面进行设置
git常用命令
git init #初始化一个本地版本库
git status #查看当前工作区(workspace)的状态
git add 文件1 文件2 #把文件添加到暂存区(Index) 使用'git add .'可以添加整个工作区文件
git commit -m"提交的信息" #把暂存区的文件提交到仓库
git log #查看当前HEAD之前提交的记录,便于回到过去
git reset —hard HEAD^^/HEAD~100/commit-id/commit-id的头几个字符 # 回退
git reflog # 可以查看当前HEAD之后的提交记录,便于回到未来
git reset —hard commit-id/commit-id的头几个字符 # 回退
git branch #显示所有分支
git branch 分支名 #创建分支
git switch 分支名 #切换到另一个分支
git clone 地址 #克隆一个存储库到一个新的目录下。
git fetch #下载一个远程存储库数据对象等信息到本地存储库。
git push #将本地存储库的相关数据对象更新到远程存储库。
git merge 分支名 #合并两个或多个开发历史记录。
git pull #从其他存储库或分支抓取并合并到当前存储库的当前分支。
Git的基本逻辑
| 名称 | 含义 |
|---|---|
| workspace | 就是你当前代码工程的目录 |
| Index | 是git的暂存区,你新创建的代码文件要add到暂存区,才能commit到版本库中 |
| Repository | 就是版本库 |
| Remote | 是远程版本库 |
四个应用场景掌握Git
这一部分将通过四个练习掌握git的本地版本库,远程版本库,团队合作和rebase的基本用法
场景一,Git本地版本库的基本用法
场景一主要是在本地对源代码进行基本的版本控制,主要通过git add和git commit -m提交版本,有了提交记录之后可以灵活地将当前工作区里的源代码回退到过去的某个版本,也就是回到过去。回到过去之后,也有可能发现之前撤销的某个版本是有价值的,希望找回来,这就需要回到未来。过去和未来之间的分界点就是HEAD,即当前工作区所依赖的版本。
第一步是进入到工作区使用'git init'创建本地版本库,创建后会出现一个.git文件
第二步创建一个README.MD文件,然后使用'git add README.MD'将该文件添加到暂存区
第三步使用'git commit -m"message"'提交这次修改
第四步修改README.MD中的内容并且再次提交
第五步通过'git reset'回到过去,此时README.MD中内容为空
场景二,Git远程版本库的基本用法
我们假定使用场景二所述的工作是串行的并且及时将本地与远程同步,也就是对于一个单人项目,要么在本地提交代码到仓库,要么通过Web页面更新远程仓库,而且这两种方式不会同时发生。不管是在本地仓库还是远程仓库,对代码修改之前都首先进行代码同步操作,防止产生分叉和冲突。
同步完成后,不管是在本地仓库还是在远程仓库提交代码,都能再次执行同步操作而不会产生分叉或冲突。
实际操作中难免会产生无法同步的情况,这时候需要在本地解决冲突,情形会稍微复杂一点。首先我们通过git pull拉取远程仓库里的提交项到本地仓库并合并到当前分支,即将origin/master中的提交项fetch到本地仓库并merge到本地master分支。
在本地版本库基本用法的基础上,只需要用推送(git push)和拉取(git pull)就完成本地仓库和远程仓库的同步
第一步,现在github上创建一个同名仓库。然后使用命令'git remote add [-t
] [-m ] [-f] [--[no-]tags] [--mirror=<fetch|push>] '为本地仓库添加一个远程仓库
第二步,使用命令'git push'将本地仓库推送到远程仓库
使用https进行推送,会要求登录github账户,如果使用ssh则要求现在github上添加你的ssh-key,登录后就可以推送成功
第三步,在github修改README.MD的内容,在实际生产中并不推荐这样做,这里只是为了模拟有别的人对代码进行了修改。我们在修改本地代码之前就要先同步远程仓库。
第四步,在修改本地代码之前先使用'git pull'命令来获取远程仓库的数据
第五步,本地修改后在上传到远程仓库
场景三,团队项目中的分叉与合并
建议团队项目的每一个开发者都采用的工作流程大致如下:
- 克隆或同步最新的代码到本地存储库;
- 为自己的工作创建一个分支,该分支应该只负责单一功能模块或代码模块的版本控制;
- 在该分支上完成某单一功能模块或代码模块的开发工作;
- 最后,将该分支合并到主分支。
场景中有两个人进行合作编程,一个是Tom一个是Jerry。
| Tom的工作流程 | Jerry的工作流程 |
|---|---|
使用'git clone'将远程仓库代码拷贝到本地![]() |
使用'git clone'将远程仓库代码拷贝到本地![]() |
| 创建Tom自己的工作分支 使用'git checkout -b 分支名'功能是创建一个分支并切换到新建分支 ![]() |
创建Jerry自己的工作分支![]() |
Tom编写自己负责的代码TomCode.txt,然后提交到本地版本库![]() |
Jerry编写自己负责的代码JerryCode.txt,然后提交到本地版本库![]() |
| 假设这个时候Tom完成了自己的开发,Tom可以将自己的分支合并到master分支然后push到远程仓库 合并自己的分支时,先切换到主分支,然后使用'git pull'确保自己当前的主分支保持最新,然后再使用'git merge --no-ff TomBranch'在保留自己分支的情况下合并到主分支,当你合并的时候git会然你编辑一个解释合并的文档,在push到远程仓库 ![]() 这里明显的出现了一些情况不让我push到远程服务器,虽然我已经pull了一次,但是jerry在我pull之后先把自己的代码push到了远程,也就是说远程仓库的项目中有我本地仓库不存在的内容,我还要在pull一次才能push |
假设这个时候Jerry完成了自己的开发,Jerry可以将自己的分支合并到master分支然后push到远程仓库![]() 这里也出现了一点小插曲,长时间没有与github联系后再次推送会要求输入账号密码,我码掉我的密码 |
此时github中出现了两人的代码

'git merge'命令的两种合并方式
默认的合并方式为"快进式合并"(fast-farward merge),会将分支里commit合并到主分支里,合并成一条时间线,与我们期望的呈现为一段独立的分支线段不符,因此合并时需要使用--no-ff参数关闭"快进式合并"(fast-farward merge)。
场景三,Git Rebase
一般我们在软件开发的流程中,有一个朴素的版本管理哲学:开发者的提交要尽量干净、简单。开发者要把自己的代码修改按照功能拆分成一个个相对独立的提交,一个提交对应一个功能点,而且要在对应的 commit log message 里面描述清楚。因此在合并和 push 之前检查修改一下 commit 记录时常需要。
场景四实际就是在场景三团队项目工作流程中增加一步Git Rebase,即在mybranch分支上完成自己的工作之后,为了让 log 记录将来更容易回顾参考,用 git rebase 重新整理一下提交记录。注意不要通过rebase对任何已经提交到远程仓库中的commit进行修改。
git rebase命令格式大致如下:
git rebase -i [startpoint] [endpoint]
#其中-i的意思是--interactive,即弹出交互式的界面让用户编辑完成合并操作,[startpoint] [endpoint]则指定了一个编辑区间,如果不指定[endpoint],则该区间的终点默认是当前分支的HEAD。
#一般只指定[startpoint] ,即指定从某一个commit节点开始,可以使用HEAD^^、HEAD~100、commit ID或者commit ID的头几个字符来指定一个commit节点
#比如下面的代码指定重新整理HEAD之前的三个commit节点。
git rebase -i HEAD^^^
git rebase —abort
git rebase --continue
这个场景中我们将进行如下操作

首先是github中的提交记录与本地提交记录对比
然后创建myBranch分支,添加rebase分支,提交三次
使用'git rebase'命令整合
这是出现要编辑的合并方法
这里选择将两个合并也一个,然后编写合并的信息
提交到远程仓库
总结
通过四个场景的练习,我们应该能够掌握git的基本用法,当然git是一个非常灵活的工具,还有更过的用法等着我们去发掘。




























浙公网安备 33010602011771号