【Android开发丨主题周】Android Studio中的13条Git实践

2020-06-12 15:39:37 浏览数 (1)

Git是一个开源、分布式的版本控制系统,与集中式版本控制系统(如SVN)最大的区别在于每个开发者都会有一个本地仓库,代码可以提交到本地,不需要依赖远程代码仓库。Git可用的图形化界面有很多,除了自带的Git GUI,还有第三方的SourceTree、TortoiseGit等。Android Studio中也自带了Git插件,已经基本上能够满足工作需求。接下来,我们一起探索Android Studio中Git的使用。

本文选自《Android应用开发进阶》一书

  • 1 创建远程仓库

通常一个项目需要创建一个远程代码仓库。我们可以使用GitHub、GitLab、码云和码市等一些代码托管平台,或者自己也可以使用Gitblit、GitLab等部署一个代码服务器。这里我们在GitHub上创建一个名为GitTest的项目。

我们创建一个空仓库,不要添加README、.gitignore、license,后续项目有需要再添加进来。因为本地代码一开始是不存在这些文件的,如果远程仓库不是空仓库,多出了那几个文件,本地代码将推送不上来。

  • 2 . gitignore

打开Android Studio创建一个项目,在项目目录下存在一个.gitignore文件,它是Git的忽略配置文件,在里面配置不需要进行版本控制的文件或目录,Git不会跟踪这些文件或目录的变化,该文件默认的配置如下:

*.iml

.gradle

/local.properties

/.idea/workspace.xml

/.idea/libraries

.DS_Store

/build

/captures

.externalNativeBuild

同样,在app模块下也有一个.gitignore文件,里面配置忽略了app模块下的build目录:

/build

我们可以手动修改这些.gitignore文件来配置忽略的文件和目录,另外还可以安装.ignore插件,更加方便地进行操作。

安装这个插件之后,就可以选择我们想要忽略的文件或者目录,点击右键,在弹出的菜单选项中选择“Add to .gitignore file”,就能在.gitignore文件中增加一行忽略配置。

  • 3 . 提交和推送

下载安装完Git之后,可以检查一下在Android Studio中的Git路径配置是否正确。使用快捷键“Ctrl Alt S”打开设置,在对话框左侧选择Version Control→Git,打开Git配置,单击Test按钮,测试Git路径是否正确。

Git路径配置正确后,就可以单击Android Studio菜单栏VCS→Enable Version Control Integration,在弹出的对话框中,选择Git。这时就会在项目根目录下生成一个.git文件夹,Git代码仓库创建完成,Android Studio左侧视窗中的大部分文件将会变成暗红色,暗红色表示这些文件还没有被Git跟踪,没有变成暗红色的文件是被忽略的文件。

Git管理代码分为工作区间、暂存区和版本库三个区域,我们在工作区间写代码,写完之后需要将创建的文件或修改的代码添加到暂存区,然后才能提交到版本库,我们不能把工作区间的修改直接提交到版本库。

接下来就可以完成第一次代码提交,用鼠标选中项目根目录,并单击鼠标右键,在弹出菜单选项中选择Git→Add,这时之前暗红色的文件就会变成绿色,表示这些文件已经被Git跟踪,添加进Git的暂存区,只有添加进暂存区的文件才能完成提交,实际上这个操作等价于执行git add命令。

然后同样选择项目根目录,单击鼠标右键,操作Git→Commit Directory,提交目录,这时就会弹出一个对话框来确认提交内容,我们必须输入提交信息,如图

表明这次提交所做的工作,然后将鼠标放在按钮Commit上,这时会弹出Commit(提交)、Commit and Push(提交并推送)、Create Patch(创建补丁)三个选项,我们可以选择“Commit”提交代码到本地后面再进行推送,也可以选择“Commit and Push”提交并推送。选择提交并推送时,会弹出对话框,让我们设置远程代码仓库的地址。

远程仓库默认的名字是origin,URL就是我们之前创建远程仓库的地址,配置好之后,单击Push按钮进行推送,代码就会上传到远程代码仓库。提交之后,文件又变回普通的黑色。

当我们再次修改代码进行提交时,就不用上述这么麻烦了,可以直接单击工具栏中的提交按钮,完成第二次提交和推送即可。提交和推送对应Git命令为:git commit和git push。

  • 4 . 分支

分支由一个个提交按时间顺序串联起来,分支与分支之间就像平行线,合并两个分支才会出现交叉的情况。创建Git仓库时,默认创建的分支是主分支master分支,当我们第一次推送时,实际上就是将本地master分支推送到远程代码仓库,这时远程代码仓库也有了一个分支,叫origin/master。在Android Studio右下角的状态栏里面有一个Git:master选项,表示当前所在分支为master分支,单击它会弹出一个对话框,如图所示。

我们可以单击“New Branch”创建一个新的分支,命名为develop,创建完成之后,我们就切换到新的分支了。这里需要注意的是,这个新分支只有本地代码仓库有,如果想要把该分支保存远程代码仓库,还需要执行推送操作:VCS→Git→Push。

我们也可以选择对话框里面的分支,完成分支的切换、删除等操作。

如上图所示,当前分支是develop分支,单击Local Branches中的master分支,也就是本地的master分支,如果在弹出的选项中选择Checkout,我们就从当前的develop分支切换到master分支,如果选择Delete就删除了本地master分支,但是远程的master分支并没有删除。如果想要删除远程master分支,则选择Remote Branches中的origin/master分支进行删除操作,同样地,删除了远程master分支,本地master分支不会被删除。

  • 5 . 获取(Fetch)

Fetch就是获取当前分支对应的远程分支最新的提交记录,可以简单地理解为同步远程分支的更新。因为在团队开发中,一个分支可能有多个开发者提交推送,那么我们本地保存的远程分支的提交记录就有可能不是最新的,所以可以通过Fetch来进行更新。操作为:单击菜单栏VCS→Git→Fetch。操作之后可以在Android Studio底部的Version Control中查看提交Log,就可以看到远程master分支,即origin/master分支其他开发者的提交记录,如下图,可以看出来origin/master分支比本地master分支多出一个提交记录。获取对应的Git命令为git fetch。

  • 6 . 拉取(Pull)

Pull就是获取当前本地分支对应远程分支的更新,然后将这些更新合并到本地分支上。实际上就是Fetch之后再Merge,操作为:单击菜单栏VCS→Git→Pull。操作之后的效果如下。

本地master分支和origin/master分支都处于同一个提交记录上,也就是本地master分支合并了origin/master分支的一个提交记录。拉取对应的Git命令为git pull。

  • 7 . 衍合(Rebase)

上节描述的拉取实际上是一种理想情况,origin/master分支和本地master分支只存在一个提交的差别,即origin/master分支比master分支多一个提交,那么合并起来是非常轻松的。但在实际工作中,通常是本地master分支多了几个提交是origin/master分支没有的,而origin/master分支也有其他开发者的提交是本地master分支没有的,这种情况怎么处理呢?

假设本地master分支多了一个第三次提交,而origin/master分支多了一个其他开发者的提交。这时本地master分支是无法将第三次提交推送到远程代码仓库的。如果强行推送,则会弹出一个拒绝的对话框。

对话框中会提示在推送之前需要先合并远程分支的变化。也就是本地master分支需要先合并origin/master分支的其他开发者的提交,然后才能进行推送。

如果选择Merge,就会合并远程分支的提交,然后再进行推送,结果如下。

从上图中可以看出来,从第二次提交开始出现了分叉,叉出来的分支实际上是origin/master分支,到最后本地master和远程master又合到了一个提交。当然这样也没有多大问题,但如果分支较多,提交记录较多,出现分叉太多则会让整体提交记录的阅读变得困难,在出现一些问题时难以梳理。为了避免出现分叉,我们可以选择“拒绝对话框”中的Rebase按钮进行衍合。衍合的作用就是将远程分支的最新的提交作为起点,再将本地分支新的提交添加在后面,衍合之后提交的记录就是一条直线,如下。

虽然Rebase能够让提交记录更加整洁,但当Rebase多个提交出现冲突时,很可能每个提交都要解决一次冲突,而使用Merge只需要解决一次冲突即可。

  • 8 . Git Flow

Git Flow是团队使用Git的一套流程和规范,主要规定了各个分支的作用。

master分支:master分支为主分支,该分支随时可以发布正式版本,所以对于稳定性的要求最高。

  • develop分支:develop分支从master分支拉出,所有新的功能和修改都会提交到该分支。
  • feature分支:feature分支从develop分支拉出,在一个feature分支上完成一个功能的开发,然后合并到develop分支,feature分支的命名最好可以描述该分支完成的功能。
  • release分支:当一个开发周期快要结束,所有feature分支都合并到develop分支后,就要开始准备发布版本了,这时需要从develop分支拉出一个release分支,release分支可命名为release-(版本号),然后使用release分支上的代码做产品测试,将bug的修复提交到release分支。当release分支测试完成后,需要合并到master分支和develop分支。
  • hotfix分支:当产品上线后出现重大bug,需要紧急修复并发布新版本时,可以从master分支拉出一个hotfix分支,可命名为hotfix-(版本号),在hotfix完成bug修改提交后,再将hotfix分支合并到master分支和develop分支,最后在master分支发布一个新的版本。

SourceTree提供了Git Flow的GUI的支持,Android Studio自带的Git插件虽然不支持,但我们可以自己完成这些分支的创建和合并等操作,另外,也可以安装Git Flow Integration插件。

  • 9 . 分支合并

如果使用Git Flow进行开发管理,那么在开发过程中会存在大量的分支合并操作,比如当一个feature分支完成开发就要合并到develop分支上。首先,我们切换到本地develop分支,因为develop分支是公共分支,其他开发者也会在上面合并代码,所以有必要拉取一下远程develop分支,确保本地develop和远程develop分支同步。这时再选择要合并的feature分支,单击右键,选择Merge,完成合并操作。

当然合并的时候可能出现代码冲突,如果出现代码冲突则会弹出一个对话框,如图。

我们一般来说会单击Merge,检查一下冲突的地方如下图。左边为develop分支的修改,中间为合并后的结果,右边为feature分支的修改,按照实际情况进行取舍,保证中间的结果是我们想要的。

这里需要注意的是,develop分支在合并feature分支时,不要选择Rebase on去衍合feature分支。这里有一条衍合的黄金原则:公共分支(master和develop)不要去衍合其他分支,否则会存在潜在的风险,具体原因可查看https://www.atlassian.com/git/tutorials/merging-vs-rebasing# the-golden-rule-of-rebasing。

  • 10 . 移动HEAD

HEAD指向的是某个分支某次提交,HEAD在哪里,那么我们在Android Studio中看到的代码就是某个提交的代码状态。有时候我们需要切换到某个提交下面查看当时的代码状态是怎么样的,那么就可以移动HEAD到那次提交上。在Android Studio的提交记录中,有一个黄色的小标签表示HEAD所在的位置。下图中,HEAD当前指向的是feature分支的“完成一个feature开发”的提交上,如果想要移动到之前某一个提交,则选择要移动到的提交记录上,单击鼠标右键,在弹出的菜单选项中选择“Checkout Revision”即可。

  • 11 贮藏(Stash)

在开发中可能遇到这样的情况,我们在一个分支上做开发,这时突然接到任务要切换到其他分支修复一个bug,但当前分支的开发并没有做好,所以还不能提交,如果强行切换分支,那么我们的修改将会丢失,这可怎么处理呢?我们可以先将修改进行保存,也就是Stash,等处理完其他任务切换回来时,再将之前保存的修改应用即可。

例如,我们在feature分支上做了一些修改但并没有提交,这时切换到develop分支,可以选择菜单栏VCS→Git→Stash Changes,这时会弹出一个对话框。我们可以在Message编辑框描述一下保存的内容,然后点击Create Stash去创建一个储藏,就可以顺利切换到develop分支。

当从develop分支切回feature分支,想要恢复之前feature分支的修改时,选择菜单栏VCS→Git→UnStash Changes,弹出的对话框如下,选择之前保存的Stash应用即可。

  • 12 重置(Reset)

在开发过程中,由于某些原因,我们想要撤销之前的提交记录,回到之前的某个提交记录上,我们可以选择重置。例如,我们在feature分支做了一个提交“待重置”,然后想重置到上一次提交“完成一个feature开发”,这时可以用鼠标选中“完成一个feature”开发的提交,单击右键,如下,在弹出的选项中选择“Rest Current Branch to Here...”

弹出一个对话框,我们有四种选择:Soft、Mixed、Hard、Keep。无论选择哪个,“待重置”这个提交记录都将删除,但这个提交修改的文件内容不一定会删除。

  • Soft

文件内容不会变化,之前提交记录的修改还是在暂存区,可以直接再提交一次。

  • Mixed

文件内容不会变化,之前提交记录的修改不在暂存区,需要添加到暂存区才能提交。

  • Hard

文件会回滚到我们选定的提交记录的代码状态,之前提交记录的修改和还没来得及提交的修改都会丢失。

  • Keep

文件会回滚到我们选定的提交记录的代码状态,之前提交记录的修改会丢失,但还没来得及的提交的修改可以储藏(Stash)起来,待重置之后反储藏(Unstash)恢复。

事实上在Android Studio中进行操作,Soft和Mixed没有太大区别,因为我们单击提交按钮时,不在暂存区的修改会自动添加到暂存区然后进行提交。但如果使用Git命令行,则必须先使用git add,然后再使用git commit。

  • 13 . 遴选(Cherry Pick)

遴选(Cherry Pick)就是将某个分支某个提交的修改应用到当前分支,作为一次新的提交。Cherry Pick直译过来为摘樱桃,非常形象生动。例如,我们在feature分支上想要“摘取”一个develop分支的提交,可以使用鼠标选择develop分支,单击右键,在弹出的选项中选择Cherry Pick。

0 人点赞