Git学习——常见问题处理
in 学习日记 with 0 comment

最近因为需要舒服的写代码,让我能在实验室的电脑上和宿舍里的笔记本都能同步写代码,我就学习了一下git。随着我使用的越来越多,后来又开始与其他同学协作来执行项目,我页用到了git中的更多功能。

当然,在其中也曾遇到了不少不理解的点和不会使用的情况,好在我都弄明白了这些问题,今天写笔记就是这样记录一下。


cherry-pick & 巧用branch

背景是这样的,我fork了一个我感兴趣的项目到了我的个人仓库中,我一股脑对这个项目进行了很多很多修改,包括readme文件的修改、代码模块化调整和很多的细节修改。

一般这时候,当我们的代码完成修改,我们只需要在原作者的仓库中开启一个pr就可以请求merge进原作者的代码了,将我的账户下的这个分支与原作者的分支进行合并即可,然而我想了一些别的事情:

我对于原仓库的修改不止一处,如文档、细节修改等,如果我一次性将我的分支合并入,会不会显得有点过于冗杂,不方便作者进行审查?

事实是,这个问题确实存在,一般情况下我们确实希望能够尽量细化我们的commit记录,使得一个pr针对于一个地方的修改,而不是一股脑地merge进原仓库。所以我们就可以使用cherry-pick来解决这个需求。

cherry pick就像是可以选择性的将commit并入分支中去。例如我的commit1是针对文档修改,commit2是实现了代码模块化调整,commit3又是针对文档的进一步修改,我们在一个分支中进行cherry pick就是可以选择性的将commit应用于分支。

最佳实践

以我刚刚的问题举例,如果要实现针对不同commit主题的pr,我们实现此需求的核心思想就是,针对每一个不同的主题新建一个branch,然后将我们仓库中与这个功能相关的commit并入实现特定功能的分支。

我的修改主题分为修改文档和代码修改,那么我就可以

  1. 在较早的commit上新疆两个分支,命名为doc和optimize
  2. (针对文档修改的分支)checkout到doc分支,在commit记录中对于文档修改相关的commit执行cherry pick
  3. (针对代码优化的分支)checkout到optimize分支,在commit记录中对于代码优化相关的commit执行cherry pick
  4. ……以此类推

这样就实现了选择性的commit,不同分支包含着对于不同开发主题、不同文件的修改。

这时候我们只需要针对不同开发主题提交一个pr即可,GitHub中会让我们选择将某一分支merge到原作者的分支中,我们只需要选择我们仓库中的不同分支进行pr即可。

这就是git的强大之处,真的很棒

2024-03-30T13:17:13.png

head,commit状态 & 进一步理解

我在pycharm中的git log gui界面中看到了很多标签的图标,不知道是什么意思,于是带着好奇去了解了一下。如下图所示

2024-03-30T13:18:06.png

2024-03-30T13:34:33.png

看起来像是我的不同的分支名,但是怎么多出了很多呢,除了我的main分支以外还有origin/main分支,怎么还多出了一个和我的项目毫无相关的HEAD分支呢?

我花了一些时间了解了一下,区分了一下。

在pycharm中的这些标签的意思代表了不同分支的最新状态,一般指向了时间最近的一个commit。就是在log历史中能够使得用户清晰的看到了不同分支是在哪里。例如我们经常可以在GitHub中看到,this branch is 2 commits ahead of main。这样的,就是让我们能够看到我们的不同的branch位置如何,到了哪一个commit。

origin/main是代表远程仓库的最新位置,而main则是代表本地仓库的最新位置。因为我们的commit可能还未push到了远程仓库。这只是一个距离,针对不同的branch名,这个标识都适用。

那么那个head又是什么意思呢?

HEAD在英语中是头的意思,就是我们最上面的最新的那个意思,所以log中的HEAD的意思就是指向分支的最新提交。他只是代表着一个指针的存在,始终指向我们当前branch的最新的commit。举例子:

总之,他总是指向了最新的那个commit,告诉我们项目的最新状态。

分离head状态 - detached HEAD state

当我们直接使用命令git checkout <commit hash>的时候,似乎看来就是将当前的工作目录恢复到了过去的某个commit的时刻,这时候head就会指向那个提交了,在这种状态下就被成为了分离head状态。在这种情况下,如果我们进行新的提交,我们的提交就不会被任何分支所跟踪,我们的提交可能会被垃圾处理。

了解了这些看似没什么用,但是可以帮助我们更加深入的了解git工作的机制和其原理,加深对其的了解。

个人对于分离head状态的理解就是,我们可以很快速方便的切换到过去某个commit上,此时对于我们审查代码,历史追踪就显得很方便,我们只需要一行命令就可以找到过去的状态,进行审查和阅读,而不需要做一些繁冗的操作。

同时,我们也可以对于过去的代码进行临时的修改、测试或者实验,而不必担心被追踪导致复杂的commit历史。

当我们做完实验后,测试完成后,如果觉得还不错, 也可以直接即时保存代码,通过创建一个新的分支git checkout -b new-branch

更改默认分支名称

上次fork了学弟的一个项目,学弟的项目已经很老了,GitHub当时默认的branch名称还是master,我作为一个强迫症其实看的有点难受,总想给他改成新的main分支名。一开始我还想了很多,想要新建一个branch然后将我的代码merge过去,再修改默认分支,最后删除旧分支,还就这么操作了。

然后结果我Google了一下就发现我是个傻瓜:GitHub中的settings有默认branch的修改选项,我直接修改就行。。。

2024-03-30T13:49:02.png

Responses