草履虫也能看懂的Git与Github与版本管理教程

写在前面

本文面向不懂什么是版本管理、不懂什么是Git、不懂怎么使用Github甚至不懂某些基本的命令行(CLI)操作的读者食用

以能够获得成果并且能够理解“我在做什么”为文章的主要目的,所以会尽量说明每一步的用途以及意义,不建议想要急于直接获得结果的读者食用(如果是的话建议直接找ai问没有学习的必要)

前述

关于版本管理

版本管理是一个很显然并且很有意义的事情,例如当你遇到一个很烦人的甲方,你提交了第一版他说不行于是你改了第二版并删除了第一版,然而他又说可能第一版更好,当你着手一步步回退到第一版时他可能又说也许第三版更好...诸如此类

虽然手改也并不是不行,但显然0个人想做这么麻烦的事。

并且,在多人协作时,也许同伴a完成了x部分的工作,同伴b完成了y部分的工作,两个人各有一份文件,我们肯定不能互相覆盖,那怎么合并呢?同样如果有版本管理的话也能解决这样的问题

对于每一个版本,你的每一次版本更新,都会包含如下的信息:改了哪些文件、改了什么内容(哪几行增了哪几行删了)、谁改的、什么时候改的、为什么改(一些备注)

这样就能够很方便的进行版本回退、版本合并等等

关于Git

git正是一个管理代码版本的工具,它可以帮助我们做一个像galgame那样存档的操作,对于每次存档(每个版本)都会记录上面提到的信息

我们将每一次存档,称为[hl]commit(提交)[/hl]

虽然git有GUI也就是图形界面的版本,但很少有人用这个吧!?我们先姑且将其简单粗暴的认为git提供了很多的命令行指令,通过这些命令行指令,我们就可以做提交做合并做各种操作。因此下面提到的内容都将是基于命令行,也就是CLI来讲述的

关于Github

这是全球最大的同性交友网站

GitHub大家应该对这个名字不陌生,大家普遍认为来说它是一个“开源代码平台”,不过更确切的说它其实是“基于git的代码托管平台“,只不过很多代码都是公开的(开源),因此大家也会在上面互相做代码学习

类比来说的话,git就是word,负责记录文档历史记录,而github则是存word的网盘

更专业一点,我们将github上新建的一个代码项目(仓库)称作远端仓库,我们通过一些指令将本地的git和远端的github仓库做连接,这样就能够通过本地的git操作将代码上传的github并做版本记录,github会展示你的每一个commit的内容

而至于协作,github提供了一个叫issue的板块用于提出问题/bug/意见、一个pull request用于让仓库管理员决定是否要合并某一次更改,至于这两个如何使用就后面再详细讲吧

终端与CLI

终端就是一个通过打字命令来控制电脑的地方,也就是很多装逼的黑客会打开的那个黑色窗口(或蓝色或白色)

而实际去执行命令的那个核心我们称其为shell。我们熟知的(熟知吗)cmd与poweshell都是windows的shell,zsh则是macos的shell

我们要输的指令都得通过终端窗口来输入,后续我们将不再一直赘述如何打开终端等等的操作,这里将直接讲清楚

对于windows系统,我们可以直接搜索cmd或者powershell——这两者在本教程中是没有区别的,不过硬要说的话powershell更强大,不过cmd也许更轻量吧!都无所谓——然后打开就可以了

对于macos,我们直接command+空格,搜索终端,同样点击即可

而更常见的使用终端的方式,是在ide中打开(ide可以理解为写代码的集成工作台,比如vscode、clion啥的),ide一般会提供打开终端的方法,以visual studio code为例,上方我们可以点击终端>新建终端,然后就会在代码编辑区下方出现一个小的终端窗口,和我们在外面打开的是没有区别的——而且方便的是,它会直接将工作目录设定在当前你打开的文件夹下

额工作目录又是什么呢——我们都知道我们写代码是要在某个文件夹下写的(或者说我们写的某个代码它应该放在某个文件夹下,我们写的某些代码应该放在一整个文件夹下),那么终端也同理,它执行的某些命令是针对“某个工作目录”的,因此知道终端当前工作目录在哪是很重要的事

例如对于macos的终端,我们直接打开时它的工作目录就是用户主目录,类似于/Users/你的用户名这样的路径

通过cd这个指令,我们可以更改工作目录,例如我们像下图这样输入并回车,可以看到用户名后面的文件夹名发生了改变,也就是工作目录发生了改变

Git的安装与使用

如何

我们可以访问https://git-scm.com/点击install进行安装,获取到安装包后直接一路next即可

如果存在打不开的可能,你可以打开终端,输入如下的指令来安装

winget install --id Git.Git -e --source winget

不管哪种安装方式,在安装完成后打开终端,输入如下命令,你应该能看到一些结果

git --version

例如下图这样

具体怎么使用,我们将在后面的流程里直接说明

Github的使用

前置准备

也不知道什么时候放开的,也不知道有没有真的放开,似乎国内现在也许应该可能可以直接访问github了

进入https://github.com/,在没有登录的情况下会要求你输入邮箱注册,没有账号的话使用学习多年的英文实力注册一下账号并登陆就可以了

登陆完成后,现在访问github看到的就是dashboard(工作台)了(中间部分做了黑色打码)

如果你乐意的话,可以点击右上角的头像,点击profile做一些好看的账户信息更改

我们平常会一直使用的东西就在头像的左侧那个书本——Repositories(仓库),每一个项目的代码我们都会创建一个仓库来保存。点击进入后可以看到所有我们提交过贡献的仓库,当然你也可以直接在dashboard左侧快速进入某个仓库,也可以点击头像后点击repositories查看所有的仓库

新建远端仓库

从新建一个仓库开始。这次我们以一个android应用项目为例(其实什么类型的都无所谓,你上传一堆txt也行)

点击右上角加号,点击New Repository,按照指引填写信息即可。注意最后的三个保持不动,不需要README.md。visibility可以按照自己的喜好选择,即使选择private也可以邀请其他人加入编辑仓库,所以看个人喜好就可以了

填写完成后点击绿色按钮,这样我们就新建了一个新的空仓库,会如下显示

接下来要做的就是将本地的代码上传到远端仓库并且建立连接

新建本地仓库并连接

配置SSH

在新建之前,我们要补充一个概念——SSH

ssh是一种用来在两台电脑之间建立安全连接的协议,协议的概念难以理解的话,可以理解为是一把安全钥匙,它能够确保两者的身份是正确且安全的,并且让两者间建立安全的加密连接

确保身份的方法是使用两把钥匙,一把称作公钥、一把称作私钥,公钥可以给别人而私钥必须要自己保存,不能暴露给任何人。公钥和私钥都是一一匹配的

我们将采用ssh的方式去连接github的远端仓库:我们首先将公钥上传给github,当我们去连接github时,公钥将尝试和私钥配对,如果配对成功,则建立安全的ssh连接

首先我们在本地创建ssh key(公钥与私钥),打开终端,输入如下的指令

ssh-keygen -t ed25519 -f ~/.ssh/github_你的邮箱 -C "你的邮箱"

你的邮箱 的部分请填写自己的邮箱,双引号请保留,这是一个注释,用来方便后续查看这把ssh的作用是什么,我们现在标注了这把key是专门给github用来ssh连接的

回车后应该会提示很多内容要求填写,不用管他一路回车就可以了,此时它会生成一对key,私钥是没有后缀的,公钥是有.pub后缀的,[hl]注意,你不应该暴露私钥到任何地方[/hl]

输入下面的指令来启动ssh agent

eval "$(ssh-agent -s)"

输入下面的指令,将ssh私钥加入,这样设备就会记住这把私钥,在ssh连接时尝试用这把私钥去匹配

ssh-add ~/.ssh/github_你的邮箱

ssh-add后的内容应该和上面指令中-f后的内容完全一致,加入完成后应该会提示“Identity added”

接着输入下面的指令获取公钥

cat ~/.ssh/github_你的邮箱.pub

这时终端应该会给出一个 以ssh-ed25519开头,以你的邮箱地址为结尾的 一长串字符,我们将整个内容全部复制下来

然后回到github,点击右上角自己的头像,找到Settings,找到左侧的SSH and GPG keys,再点击右上角的绿色按钮来创建

Title可以随便填写,你可以写你的设备名字(因为ssh是跟着设备走的),然后将刚刚复制的内容黏贴到下面的Key一栏里,随后点击Add SSH key——这样我们就将公钥交给了github

回到本地终端,输入

ssh -T git@github.com

第一次连接时,会提示

Are you sure you want to continue connecting (yes/no)?

我们输入yes然后回车就可以,不出意外就会显示

Hi [你的github用户名]! You've successfully authenticated...

新建本地仓库

回到github,点击右上角头像,点击Repositories,找到我们刚刚新建的仓库,点击进入,这样就回到了当时新建完成后出现的页面

我们找到Quick setup,选择SSH

复制下方第一块内容中的指令(可以直接点击右上角复制)

然后回到本地的项目,请注意一定要进入到项目的工作目录内而不是再上一层,以vscode为例,我们点击最上册的文件夹后应该能看到很多个相关的文件夹,而不是需要再打开一层

此处以Android Studio为例,Android studio打开时会默认就在工作目录下,因此不需要再额外修改终端的工作目录

我们打开左下角的Terminal,此时下方就会出现终端窗口

将刚刚在github复制的内容黏贴到此处并回车,出现类似下面的内容就代表连接成功了

简单解释一下指令的含义——(忽略第一行)

git init

代表初始化git仓库,从此以后该工作目录下的所有更改都会被git仓库追踪,也就拥有了版本管理的能力,初始化会在工作目录下创建一个隐藏的.git文件夹

git add README.md

add代表把README.md这个文件加入[hl]暂存区[/hl],git有三个区域:工作区(正在写的东西)、暂存区、仓库(正式代码),提交到暂存区的部分在后续才会被正式commit和上传

此处我们只上传了一个readme文件,后续我们可以通过 git add . 来一次性上传工作目录下所有有更改的部分

git commit -m "first commit"

commit就是我们前述中提到的一次存档,代表正式提交了一个[hl]版本[/hl],-m后面的内容代表对于此次commit的说明,这是一个很重要的部分,方便后续追踪——一般来说,commit的说明编写是存在约定俗成的规范的,后续我们将给出一个常见的commit说明的编写方法

git branch -M main

代表强制重命名当前分支为main,以前叫master不过现在大家都叫main

分支就是一条独立的版本发展路线,一般来说正式的版本分支会称之为main,可以类比为现在正在写一本小说,主线任务称之为main,不过偶尔作者也想试试看新的结局分支,可能称之为new-ending

如果写着写着发现写崩了,那么我们可以直接删除这条分支;不过如果发现写的很好甚至能够对主线做贡献,那么就可以将这条分支和main合并

对于多人协作的项目,我们可以通过分支来让不同人完成不同模块,最后写好了的话统一进行合并即可

git remote add origin git@github.com:MintCat233/music-player.git

代表绑定远端仓库,origin后面的内容就是远端仓库的地址,github在这里帮我们生成了

git push -u origin main

将刚刚的commit全部都推送至github的main分支下,-u代表跟踪,这样以后就不用再写origin main而是可以直接git push,不过为了分支管理方便,还是建议每次都是用git push origin main

这时我们打开刚刚的github仓库页面并刷新,就能看到仓库中有一个readme文件。根据上面讲到的内容,我们再输入下面的指令,将工作目录下的所有内容全部推送至远端仓库

git add .
git commit -m "init android project with default template"
git push origin main

再刷新,就可以看到仓库页面里面有了所有代码

可以看到,每个文件的后面都有文字说明,代表在某次commit中修改了这个文件,文字内容就是commit的注释内容

在仓库标题的下方,可以看到main分支的标识,以后如果有新的分支将会在这里显示,右侧也显示了当前一共有多少分支

在分支下方显示的头像与用户名代表最近一次的commit的提交者,右侧是提交的commit的信息,再右侧的7位字符是本次commit的哈希值用以唯一标识本次commit

日常的工作流程

初次拉取代码到本地

对于一个需要共同协作这个仓库的代码的开发者,第一步就是将远端仓库的代码拉取到本地

首先,你需要获取仓库地址。进入仓库的github页面,点击绿色的Code按钮,选择SSH,然后点击复制

接着回到本地,找一个你喜欢的文件夹,打开终端

[buy]对于windows用户,你可以打开你需要的文件夹,然后shift+右键点击空白处,随后选择“在此处打开 PowerShell 窗口”或者“在终端中打开“即可

对于macos用户,首先进入finder并点击电脑屏幕右上角的“显示”,找到“显示路径栏”并点击,随后在需要的文件夹中右键下方对应的文件夹名,点击”在终端中打开“即可

[/buy]

在终端中输入

git clone 你刚刚复制的内容

例如git clone git@github.com:MintCat233/music-player.git,然后回车即可,这样他就会在你选择的文件夹下再生成一个以仓库名命名的文件夹,这就是项目代码了

提交一次commit

规范

也许你想说,我们先库库写着,写完了然后想干别的事了,再来看看这个commit怎么提交吧

其实这并不是一个很好的做法,我们应该首先了解commit规范,然后了解什么时候应该做一次commit

本文以及本文作者会依照约定式提交给出的规范做简单的讲解,如果你需要了解更加正式的规范详情可以直接戳前面的链接看,是有中文的

对于一次commit,我们应该按照如下的格式去写commit说明

<类型type>(涉及范围scope 可选): <描述description>

[主体正文body 可选]

[脚注footer 可选]

标注了可选的都是不一定要每次都填写的,不过类型与描述是一定需要的

例如下面是一个全部包含的例子,虽然是英文的,但是你完全可以写成中文(type不要写成英文!)

feat(player): add play/pause toggle

Add a button to control playback state

Refs: #12

对于类型type有如下的常用的类型

类型含义
feat新功能
fix修bug
docs文档
refactor重构(不影响功能)
style格式(空格、缩进、格式化)
test测试
chore杂项(配置、脚本等等)
build构建相关
ciCI/CD

如果你不确定是什么type,你可以问问ai

有人可能问,那如果我又写了新功能又修了bug呢?——实际上,你应该避免这样的情况的发生,也就是说,当你完成一个新功能时就应该做一次commit,而不是拖到最后

对于描述,应该写的尽量简洁并且可读,如果你认为有需要补充的部分,可以进一步详细写在正文中,而不是在description里写流水账

footer一般用于关联issue或者标记重大变更,issue就是其他人提出的问题/bug/意见等,每个issue会存在一个编号,不过这些我们后面再说——既然footer是可选的不管也可以

所以一个简洁的普通的commit可以写成:

feat: 增加播放按钮和ui框架

如何提交

在了解了规范以后,我们知道我们应该以type为分类做多次commit——不用担心push的时候会不会只commit一个,它会把所有的commit都一起推送了

根据下面的实例,来看一下如何提交一次规范的commit并推送

在刚刚上传的初始代码的基础上,我对项目做了一些文件上的组织,例如我新建了一些文件夹,告诉后面的开发者你应该在这个文件夹下写什么内容(我这里在ui文件夹下新建了一个components文件夹和screen文件夹),随后在screen下新建了一个HomeScreen.kt文件

对于Android Studio这种IDE,会在你新建文件时提示你是否要加入git的暂存区,你可以选择Add,不过当然后面手动git add也完全可以,这里为了教程方便我们先暂时不加入

首先,这里使用add来加入暂存区

git add .

接着编写commit,我们可以用下面的方式来编写多行commit,首先输入

git commit

回车后我们便进入了commit编辑器,这样就可以换行编辑了

这里我们写一个带body的commit吧,例如下面这样

写完以后,按一下esc并输入

:wq

注意是英文冒号,随后回车,就能看到类似这样的

mitorimatsumoto@MitoriMatsumotodeMacBook-Air MusicPlayer % git commit
[main 7fbf8ce] chore: 新建文件夹以组织文件结构,并新建HomeScreen占位
 1 file changed, 2 insertions(+)
 create mode 100644 app/src/main/java/com/androidcourse/musicplayer/ui/screen/home/HomeScreen.kt

当然,如果你只写type和description不写body的话,可以使用然后直接回车,这样就不用这么麻烦

git commit -m "chore: 新建文件夹以组织文件结构,并新建HomeScreen占位"

接着推送

git push origin main

稍作等待后,回到github页面,就可以看到我们成功提交了一次commit,点击commit内容旁边的三个点就可以看到本次commit的详细信息(body)

获取别人的改动

当然,在多人协作中,我们肯定不能只一个人一直提交代码而不获得别人的提交

因此我们需要拉取代码

正常拉取

在没有冲突的情况下,我们直接

git pull

就可以获取最新的改动

冲突处理

不过,有的时候可能会出现两个人同时编辑一个文件的情况,或者两个人同时在本地工作,一个人提交了更新但另一个还没有pull就继续在旧版本上更改

如果在这个时候做commit并push,可能会提示冲突或者版本落后

此时,我们可以先尝试直接进行

git pull

如果没有冲突(例如你们虽然在修改同一个文件,但是修改的部分各自不搭噶),那么git会自动处理并做合并

如果有冲突,git则会提示你哪些部分是冲突的,你需要自己手动处理这些冲突,最后再做一次正常的提交

显然,每次都手动处理冲突是一个代价很大很麻烦的事,因此我们更推荐进行分支管理

分支管理

前面我们提到了分支的概念,这里来实际操作一下如何新建一个分支并且在分支上做改动

例如,我们新开一个专门用来开发HomeScreen的分支,-b后面就是这个分支的名字,功能开发一般以feature开头

git checkout -b feature/HomeScreen

接下来随便写点什么并且做一次commit,例如

git add .
git commit -m "feat: homescreen简单显示"

接着push,不过注意这次push需要到前面我们新建的分支去

git push origin feature/HomeScreen

此时我们回到github的仓库页,可以看到这样的提示

如果我们完成了这个分支的开发,就可以提出[hl]Pull request[/hl](简称PR),将分支的代码合并到main分支下

假设此处我们已经完成了开发,点击Compare&pull request,进入PR提交页面

在Comparing changes下的一行,我们可以看到base:main和compare:feature/HomeScreen,base代表目标分支(我们要合并到main),compare代表你的分支(你的代码来源),后面提示的“Able to merge”代表此次merge不需要手动处理冲突,可以直接合并

接着填写PR的title和description——对于某些公开的代码仓库,有的时候仓库管理者会提供PR的提交规范,必须阅读并按照规范填写必要的部分。不过如果是熟人团队开发,则可以自己按照约定俗成的方式去提交PR

接下来就是仓库管理者进行Code Review(代码审阅),检查你的分支是否有问题是否可以合并,如果可以就会由管理员进行merge

管理员将在对应PR看到下面的页面,如果没有冲突就可以直接点击Merge pull request,将分支merge到main分支下

当然,管理员也可以选择要求你更改分支的代码,此时你不需要做额外的操作,直接在你的代码的基础上修改并且继续推送更新到对应的分支上,PR会自动更新

成功merge后,本次PR将会closed(被关闭),main分支也会同步更新,为了方便,你也可以直接点击Delete branch来删掉这个分支(你想继续开发也可以,重新提交PR就好)

如果你完成了这个分支的开发,你可以输入下面的指令来回到main分支

git checkout main
git pull origin main

在此基础上,如果你需要开新分支继续开发,可以再次重复一遍最开始的过程

总结

综上,对于一次比较优秀规范的协作开发,我们应该按照如下的流程

  1. git clone 拉代码 或者 新建仓库并连接
  2. git checkout -b feature/xxx 开分支
  3. 写代码
  4. git add .
  5. git commit
  6. git push origin feature/xxx
  7. 提交 Pull Request
  8. 等待审核并 merge
  9. git checkout main
  10. git pull 更新主分支

写在后面

我也不知道后面要写什么,如果你有任何不能理解的部分,可以直接在评论区提出或者直接通过各种联系方式联系我

posted @ 2026-04-27 15:04  Mitori  阅读(37)  评论(0)    收藏  举报