Git项目工作流程演练
Git介绍
Git作为一款优秀的分布式版本控制系统,目前已经成为程序开发人员做项目版本管理的首选。
我们在学习Git的常用命令之前,先了解一下Git的结构。首先,Git将文件分为四个不同的区域,分别为工作区,暂存区,本地版本库和远程版本库。工作区,顾名思义就是你在电脑里能够看到的目录,在工作区中有一个隐藏目录.git,这个不算工作区,而是git的本地版本库。本地版本库里存了很多东西,其中最重要的就是称为stage的暂存区,还有Git为我们⾃动创建的第⼀个分支master,以及指向master的⼀个指针叫HEAD,HEAD指向的就是当前分支的最新提交。至于远程版本库,一般指的是Git服务器上所对应的仓库,本文的示例所在的github仓库就是⼀个远程版本库。
开发流程演练
接下来,我们按照孟宁老师提供的微信文章中的场景四的练习,来模拟实际的开发流程,截图如下:
虽然Git是分布式的系统,但在实际开发过程中,我们仍然需要搭建一个中心仓库用来分享自己的代码或者与其他开发人员合作,Github作为Git的最佳搭档自然是我们的首选。在Github上建立一个开源项目仓库,项目名为learn_github,添加README文件,协议为MIT LICENSE。过程比较简单,直接贴结果:
git config 命令
接下来我们要把本地仓库与远程仓库进行关联,这里使用SSH公私钥的方式进行身份认证。首先我们在本地打开Git Bash命令窗口,进行最小化配置,命令如下:
$ git config --global user.name 'your_name' # 配置当前用户的所有仓库的用户名 $ git config --global user.email 'your_email' # 配置当前用户的所有仓库的邮箱 $ git config --global --list # 查看当前用户的全局配置
接下来我们开始配置公私钥,具体流程可以参照Github官方教程。
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
由于我之前已经配置过,所以直接将公私钥复制粘贴到Github个人主页的SSH-Keys中。
git clone 命令
然后将项目从Github远程仓库中拉取到本地仓库并完成初始化,我们使用git clone命令。
$ git clone git@github.com:huch-er/learn_github.git # 使用SSH方式拉取代码 $ git clone https://github.com/huch-er/learn_github.git # 使用HTTPS方式拉取代码
之后,我们就得到了如下图所示的项目文件目录:
现在已经准备就绪,可以愉快地进行coding了。
git branch 命令
在Git中有分支模型的概念,刚创建时默认只有一个主分支Master。我们采用Git flow的分支模型,一般情况下,主分支Master是功能最为稳定最为完整的可随时发布的代码,此外,我们再创建一个从分支develop,表示我们正在开发的项目版本。代码如下:
$ git branch develop # 创建分支develop
如果我们想要查看分支信息,可以使用如下命令:
$ git branch -a # 查看本地和远程仓库的所有分支 $ git branch -r 分支名 # 查看远程仓库的分支列表,加上-d参数可以删除远程版本库的分支 $ git branch -vv # 查看带有最后提交id、最近提交原因等信息的本地版本库分⽀列表
如果我们想要删除不需要的分支,使用如下命令:
$ git branch -d 分支名 # 删除远程版本库的分支
$ git branch -D 分支名 # 分支未提交到本地版本仓库前强制删除分支
git checkout 命令
紧接着我们需要切换到develop分支进行开发。
$ git checkout develop # 切换到develop分支
git status 命令
接下来我们创建第一个代码文件A,然后查看git的状态。
$ touch A $ git status
git add 命令
这里Git提示有一个标红的文件没有被它管理,这就涉及到工作区和暂存区的区别,我们之前所写的代码默认是放在工作区中的,而工作区是不会被Git所管理的,要想Git管理该文件,需要将文件提交到暂存区中,需使用git add命令。
$ git add <file_name> # 将指定文件提交到暂存区
$ git add . # 将工作区所有文件提交到暂存区
再次使用git status命令查看状态。
git commit 命令
此时git显示有新文件被纳入暂存区,标记为绿色,我们还需要使用git commit命令将暂存区的文件正式提交到本地版本仓库中。
$ git commit -am 'add A'
如果我们想要修改最新commit的message信息,使用如下命令:
$ git commit --amend -m '修改的提交信息'
git log 命令
现在本地仓库已经有A文件了,我们按照以上方式实现文件B的操作,并使用git log命令查看最近的几次提交记录。
$ touch B $ git add B $ git commit -am 'add B' $ git log
git reset 命令
现在我们对文件A和B进行修改,但发现修改的内容不是很理想,想要回退到原先的状态,此时我们修改的内容并没有提交到Git中,这里涉及到git reset命令,此命令可以将当前的分支重设(reset)到指定的 <commit>或者 HEAD,下面列出常用的操作命令以供参考。
$ git reset HEAD/<commit> # 退回到某个版本,保留⽂件内容,回退提交历史 $ git reset --soft <commit> # 暂存区和⼯作区中的内容不作任何改变,仅仅把HEAD指向<commit> $ git reset --hard <commit> # ⾃从<commit>以来在⼯作区中的任何改变都被丢弃,并把HEAD指向<commit> $ git reset HEAD -- file_name # 取消暂存区部分文件的更改 $ git checkout -- file_name # 将工作区文件恢复成和暂存区一样
文件A默认为空,我们对A进行修改,然后回退到空版本。
git stash 命令
现在我们遇到这样一种情况,当我们在一个分支里开发一个功能时,此时遇到了一件紧急任务需要马上处理,而我正在开发的代码还尚未提交,这时我们需要将代码放到git为我们提供的栈stash中,之后就可以着手处理紧急任务了。这里的栈stash与我们数据结构中所学的栈一样,后进先出,用于保存当前修改或删除的工作进度。这里给出常用得到git stash命令以供参考。
$ git stash # 将当前工作区存入堆栈
$ git stash apply # 从堆栈上面取出stash,相当于get top
$ git stash pop # 从堆栈上面取出stash,相当于get pop
$ git stash list # 查看堆栈里的stash
文件A默认为空,修改之后放到堆栈,然后再取出。
git pull 命令
现在我们在develop分支创建了A和B文件,然后切换到master分支创建C和D文件,现在我们想把develop和master分支进行合并,但是在合并之前,我们要从远程仓库拉取最新的代码到本地仓库,目的是防止本地文件与远程文件发生冲突。
$ git checkout main $ touch C $ git add C $ git commit -m 'add C' $ touch D $ git add D $ git commit -m 'add D' $ git pull https://github.com/huch-er/learn_github.git
git diff 命令
现在已经将远程仓库代码拉取到本地,如果远程仓库代码做了变动,而我们本地的代码也有变动,那么就会产生冲突,⼀般情况下 Git 会自动处理这种冲突合并,但如果改动的是同⼀行,那就需要手动合并代码,编辑相应的文件,保存最新的改动,再通过git add和git commit来提交合并。这里需要用到git diff命令查看文件的差异,具体如下:
$ git diff --cached <file_name> # 查看暂存区和HEAD指针所含指定文件的差异 $ git diff <file_name> # 查看暂存区和工作区指定文件的差异 $ git diff <commit> <file_name> # 查看工作区同本地仓库指定commit的内容的差异 $ git diff <branch1> <branch2> -- <file_name> # 比较两个分支对指定文件的差异 $ git diff <commit1> <commit2> # 任意两次commit的差别
git merge 命令
现在我们解决了文件之间的冲突问题,要把develop分支中的文件合并到master主分支中。这里使用git merge命令:
$ git merge # 默认情况,执行“渐进式合并”,会直接将Master分支指向Develop分支
$ git merge --no-ff # 执行正常合并,在Master分支上生成一个新节点,保证版本演进更清晰
下图更容易理解
使用git merge命令的效果如下,这里我们使用gitk命令查看图形界面:
git rebase 命令
现在按照孟宁老师文章中的场景四的练习要求, 如果master和develop分支上的这些开发部分都是同一个人操作,在合并的时候不想产生这种分叉的结果,怎么办呢?这里我们用到了一个比较复杂的命令git rebase命令,用在从上游分支获取最新commit信息,并有机的将当前分支和上游分支进行合并。因为develop分支是在master分支基础上建立的,所以master称为develop的上游分支。
$ git rebase -i [startpoint] [endpoint] # 该命令指定了一个编辑区间,如果不指定[endpoint],默认为当前分支的HEAD
一般只指定[startpoint] ,即指定从某一个commit节点开始,可以使用HEAD^^、HEAD~100、commit ID或者commit ID的头几个字符来指定一个commit节点,执行如上命令后,会自动弹出一个交互式界面让我们操作。
将第一行的pick改成Commands中所列出来的命令,然后保存并退出,所对应的修改将会生效。如果移动提交记录的顺序,将改变历史记录中的排序。
现在我们要把A和B合并成一个commit,使用s参数进行合并,操作如下:
然后在弹出的界面里修改提交信息,这里我们设置为A and B。
然后通过git reset命令恢复到master合并之前的状态,然后切换到develop分支执行如下操作:
gitk显示的图形界面:
之后,切换到master分支,执行git merge操作即可。
此时,gitk显示的图形界面:
如果我们想撤销该操作的话,使用如下命令即可:
$ git rebase --abort
此时,我们就实现了场景四所要求的练习效果。
git push 命令
最后我们将主分支代码推送到远程版本库。
$ git push git@github.com:huch-er/learn_github.git
至此,项目开发的大致流程以及常用的git命令介绍完毕。
Git总结
以上就是Git的大概知识点,掌握以上命令和操作就可以应付一般的工作开发流程。最后我们用图片进行总结,毕竟一图胜千言。
工作区、暂存区、本地版本库和远程版本库之间几个常用的 Git 操作流程如下图所示:
浙公网安备 33010602011771号