Git 的正确使用姿势与最佳实践 | 青训营

323 阅读6分钟

Git 的正确使用姿势与最佳实践

由于我们组的队员大多都是大一大二的学生,之前大家都没有真正的工程实践经验,都听过Git是一个公认的版本控制神器,但是没有深度的使用过。刚好这次做大项目,是一个很好的机会好好研究一下Git的正确使用姿势。这篇文章就整理和记录一下学习和使用Git的过程。

开发环境说明

我们准备在GitHub上面建一个代码仓库用来存放项目代码,开发环境就直接使用1024code的代码空间。

接下来我们会记录一下从一开始创建代码仓库、代码空间,到在1024code上面连接远程空间、每个人分别在自己的代码空间用自己的分支进行开发,到最后提交代码、创建Pull Request、合并代码的整个过程。

准备工作

创建GitHub仓库

通过github.com/new来创建一个代码仓库,填好基本信息之后,点击Create repository完成创建。

这里我们创建的仓库地址是

github.com/claw16/git_…

创建1024code代码空间

1024code.com主页点击上面的工作台,然后新建。这里我们选择Go作为代码模板,空间叫做git_demo。空间地址:1024code.com/ide/hhn4izj

代码空间连接远程仓库

在左边侧边栏有一个git图标,里面有一些使用Git的基本说明。我们选择“连接远程仓库”。按照说明,我们先添加公钥到GitHub。

然后在代码空间的shell命令行里面配置SSH连接

~/app$ git remote add origin git@github.com:claw16/git_demo.git

没有出错的话默认不显示任何返回信息。

接着拉取远程仓库:

~/app$ git pull --rebase origin main
The authenticity of host 'github.com (20.205.243.166)' can't be established.
ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 618 bytes | 77.00 KiB/s, done.
From github.com:claw16/git_demo
 * branch            main       -> FETCH_HEAD
 * [new branch]      main       -> origin/main
Successfully rebased and updated refs/heads/master.

从上面的信息可以看到我们成功拉取了github.com:claw16/git_demo这个仓库的main分支。

开发流程

做了一些功课,我们大致了解了一下敏捷开发的工作流程。这里总结一个简化的版本:

  1. 分配任务,把每个任务写成一个JIRA ticket,分配给对应的开发者。

  2. 开发者拿到任务后,根据这个任务,建立一个自己的开发分支(从主分支拉取),进行开发工作

  3. 开发完成后,将开发的代码推送到远程仓库

  4. 创建一个Pull Request,指定一位合作开发者来审核代码

    1. 如果审核测试的过程发现了问题,需要重新修改,然后重复3、4步
  5. 审核完成后合并代码到主分支

我们来模拟实践一下这个开发过程。

分配任务

假设我拿到这样一个任务:

编写README.MD

开发任务

我们先从主分支上新建一个新的分支,叫做edit_readme

~/app$ git checkout -b edit_readme
Switched to a new branch 'edit_readme'

可以看到我们已经新建并且切换到了edit_readme分支上,现在就可以开始开发了。

我们先修改一下README.MD,在里面加一行: Edited this file at 16:31 on 20230823.

然后查看一下当前的文件变化:

~/app$ git status
On branch edit_readme
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   README.md
​
no changes added to commit (use "git add" and/or "git commit -a")

可以看到这里显示README.md被修改了。

然后我们添加这个修改的文件,然后commit:

~/app$ git add README.md 
~/app$ git commit -m "1st commit"
[edit_readme 58a917a] 1st commit
 1 file changed, 2 insertions(+)

一般来说,开发的过程肯定不止一个commit,这里分享一些commit的好习惯:

  1. 每一小步commit一下,例如完成了一个功能,修复了一个bug,等等。这样审核的人通过我们的commit message就可以了解每一步做了什么
  2. 不要半途commit,如果一个功能做到一半,这个时候commit是一个不太好的习惯。如果非要commit,那么下次回来继续完成后半部分的工作之后,可以用 git commit --amend 命令将后面一般的改动加到上一次的commit中
  3. commit之前充分测试我们的改动,可以的话最好写点必要的单元测试
  4. 尽可能清楚详尽地把我们做的改动写进commit message里面

然后同样地,我们接下来又开发了两个小功能,每一个都对应了一个commit。

我们可以用 git log 命令查看我们的commit记录:

~/app$ git log
commit 06ec0e09b6a61f5a3fb36aec60e2052e43a6bde8 (HEAD -> edit_readme)
Author: for shell <fromShell@paas.com>
Date:   Wed Aug 23 17:23:59 2023 +0800
​
    fixed a bug
​
commit 39666635c64aa534c9d419a486a8af47ef8dd107
Author: for shell <fromShell@paas.com>
Date:   Wed Aug 23 17:23:31 2023 +0800
​
    developed a new feature
​
commit 58a917a79747cf6c9f058e9827428153aef3d4a1
Author: for shell <fromShell@paas.com>
Date:   Wed Aug 23 17:15:56 2023 +0800
​
    1st commitcommit e54434b69036d17daa663cb3548f60db51c337fa (master)
Author: root <root@manager>
Date:   Wed Aug 23 15:31:47 2023 +0800
​
    Initial commitcommit 211147aa340c72f780034e2cabe8022a4865d27e (origin/main)
Author: claw16 <52300404+claw16@users.noreply.github.com>
Date:   Wed Aug 23 15:09:44 2023 +0800

可以看到在edit_readme分支上我们有3个commit。

提交以及创建PR(Pull Request)

假设我们现在完成了开发,我们就可以把我们的改动提交到远程仓库:

~/app$ git push origin edit_readme
Enumerating objects: 17, done.
Counting objects: 100% (17/17), done.
Delta compression using up to 16 threads
Compressing objects: 100% (14/14), done.
Writing objects: 100% (15/15), 1.38 KiB | 1.38 MiB/s, done.
Total 15 (delta 5), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (5/5), done.
remote: 
remote: Create a pull request for 'edit_readme' on GitHub by visiting:
remote:      https://github.com/claw16/git_demo/pull/new/edit_readme
remote: 
To github.com:claw16/git_demo.git
 * [new branch]      edit_readme -> edit_readme

可以看到这里将我们的分支上传到了远程仓库,并且在远程仓库建立了一个同名分支。同时也自动生成了一个链接,用于让我们创建Pull Request。我们可以直接打开这个链接。

在打开的窗口中,我们填写好PR的标题,言简意赅的表述一下这个PR做了什么,指定审核人,最后创建PR。

注意:如果我们不是通过自动生成的链接来建立PR,或者说链接有什么问题,我们就需要手动创建。手动创建时,除了刚才说的几个步骤之外,我们还需要手动指定从哪个分支合并到那个分支。

image.png

合并代码

当审核人完成审核,没有问题了,就可以直接点击Merge pull request,这样我们的分支就合并到远程仓库的主分支里面了。

后续开发

到这里还没有完全结束。到这里位我们只是完成了远程仓库上的合并分支操作,我们还需要将这个修改同步到本地。

我们需要先切换回主分支,然后在主分支上拉取一下远程仓库的主分支:

~/app$ git checkout main
Branch 'main' set up to track remote branch 'main' from 'origin'.
Switched to a new branch 'main'

可以看到现在切换回本地主分支了,然后之前做的修改也对应的回到了最初的状态。这时我们拉取远程主分支。

~/app$ git pull origin main
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), 610 bytes | 203.00 KiB/s, done.
From github.com:claw16/git_demo
 * branch            main       -> FETCH_HEAD
   211147a..e1bf84d  main       -> origin/main
Updating 211147a..e1bf84d
Fast-forward
 .1024      | 9 +++++++++
 .gitignore | 6 ++++++
 README.md  | 6 ++++++
 go.mod     | 3 +++
 main.go    | 9 +++++++++
 5 files changed, 33 insertions(+)
 create mode 100644 .1024
 create mode 100644 .gitignore
 create mode 100644 go.mod
 create mode 100644 main.go

可以看到远程主分支的内容现在同步到本地了。

后续的开发就可以从更新后的主分支开始。

总结

这篇文章记录了在一个开发过程中如果正确地使用Git来进行代码管理。这只是一个精简的流程,实际开发中会遇到很多不同的场景。比如:

  1. 将本地的几个commit合并成一个commit提交给远程,可以用 rebase 功能
  2. 本地开发时不小心直接在主分支上操作了,可以用 git stash 功能来把当前的修改暂时隐藏并且存到一个栈里面,再切换到正确的分支用 git stash pop 操作把暂存的修改应用到正确的分支。
  3. 发现之前开发的东西有问题,可以使用 git revert 功能来回滚

Git是一个强大的代码管理、版本控制的工具,学好Git可以帮助我们更好地编程。