前排提示,这玩意想玩明白真的很麻烦,如果你时间不够,建议直接U盘同步工作,换言之,我感觉这玩意比 Qt 还难学,如果助教强制要用了,那最好早点开始学,不然肯定寄了
Git 在干嘛
简单说就是版本管理,你可以在每次修改完代码后通过 Git 保留一个快照,这样在你发现写错了的时候可以快速回档和比较自己改了哪里。
GitHub 在干嘛
GitHub 和 Git 其实是两个东西
- GitHub 提供了一个远端存储代码的地方,你可以用它来远程同步代码
- 如果你把代码公开,那它就是一个开源代码仓库,你可以分享你的开源代码,也可以下载他人的开源代码
- 团队协作,这是 GitHub 很重要的内容
万事开头难,但这次很简单:配置 GitHub 和 Git
- 下载安装Git
- 注册 GitHub,可能需要魔法
- 下载 GitHub Desktop
- Git 所有更改需要署名,记得用和 GitHub 注册时一致的邮箱
git config --global user.name "Jarden"
git config --global user.email "1747366367@qq.com"
基本流程
先不管命令,我们讲一下 Git 和 GitHub 一般的流程。
首先在 Git 里面,一般你每写了一个很重要函数,或者增加一个功能,或者修了一个Bug,或者重构了一个功能,你就会提交一个commit。
- 比如我今天把棋子的初始化写了,我提交了一个commit。
- 然后我写了点击一个棋子它要发送一个信号给棋盘,我提交了一个commit。
- 然后我突然不想要点击棋子然后发送信号了,我想直接通过点击的时候判断我鼠标的坐标属于哪个棋子,然后来执行对应功能。那我就直接退档到我写棋子之前了。怎么退这里先不讲
然后再想象一下你下周要交大作业的第一阶段成果了,不过你们进度很快,已经在写下一阶段了,可是这时候你们突然发现你们的代码有个Bug。
助教开开心心的 clone 了你们的代码然后一跑,炸了。然后代码炸了,助教炸了,你们也炸了。
但是你们写完第一阶段的时候其实已经测试过了,能跑,一种是你告诉助教回退到哪里,不过有点麻烦。
比较好的方法是给工程分配 branch,比如一般 master 是开箱即用的,理解成稳定版。然后 dev 是开发版,然后如果很多个人在写代码的话,可能每个人在写一个功能的时候都会重新开一个分支。分支的作用就是保证我在改的时候不会影响到开发主线,我支线可能正写得一团糟,改完都跑不了,但是只要我不 merge 回主线,那主线还是开箱即用的状态。等我写完测完了,我就可以 merge 回去了。
命令学习
如果想面面俱到,可以看比如 Git Pro 这本书。不过如果你只是想应付大作业,那大可不必看这么厚的一本
常用指令的教程这个人写的很好,关注它的公众号搜 Git,全看完就差不多会了。
一些补充
上面的教程好像没讲回退,简单的回退看这个即可,还有一种是反做,蛮神奇的
还有一种东西就是删除和改名(移动)了,如果你直接像操作资源管理器一样去操作,结果可能和你想的不太一样。文件管理器删除后,git 里面这个文件会一直存在,要在 git 中也删掉,得用 git rm 而不是系统级的 rm
git mv --help
git rm --help
VSCode
如果你打开 git init
后的文件夹,这时候你会发现你的 VSCode 不太一样了,VSCode 里面提示的意义可以看这篇。或者你也可以不管(
选择什么工作流
这里讲一个我最开始误区,GitHub 和 Git 是两个东西,比如 pull request 和 fork 就是 GitHub 特有的东西,它要到 GitHub 里面去操作。
首先你要创建一个组织,把你队员拉进去,然后创建一个项目。或者你自己的账号已经创了,那就改所有权。
然后网上如果直接查GitHub协作,你会看到很多 forking 工作流,但是这个东西比较适合非信任的团队开发,比如你不希望一个实习生搞糟了整个项目,或者你是开源的项目,然后什么人都可以改那肯定完蛋。但是我们这个应该不属于这一类
具体怎么选择可以看这个包括它下面的推荐阅读都挺好的
.gitignore
你肯定不想git add 的时候手动筛选哪些要同步,比如你新建了一个test.cpp来测试一个小代码,它不属于这个项目。你可以用 .gitignore 来帮你自动在git add . 的时候排除一些文件。老样子,不生产教程,我是教程的搬运工
令人烦恼的冲突
解决冲突是一个很麻烦的事情
比如最开始前四行是同步的,然后远程提交了一个哥哥好帅
结果你自己在本地写了个我好爱
这时候你 git push origin master
是肯定失败的。这个失败是无关冲突的,只是因为你的版本不是最新的,这是很正常的。
所以首先你先尝试 git pull origin master
一下,或者先 fetch
再 merge
,后者似乎更好,前者是没有冲突的时候就自动成功了,后者是有冲突的时候用的。
在有冲突的情况下会这样,正常你看到的是。
hhh
ggg
www
lll
<<<<<<< HEAD
哥哥好帅
=======
我好爱
>>>>>>> 4bd31ac (a)
如果你不幸冲突(迟早会的),那么可以看看这个,简单来说 Git 的解决方法就是把分叉之后所有的 commit 回退到工作区,然后你解决完冲突后,重新变成一个 commit 然后 merge 回去
还有一个知乎问题,如何克服解决 Git 冲突的恐惧症
解决冲突最好的方法还是一开始就不要冲突,尽可能把文件拆开,然后一个人写一个人的。所以如果你就两个文件,那你死定了 。另外就是频繁地 push 和 pull,稍微写一点就同步一下,免得最后看到几百行的冲突
merge 的时候也会冲突,其实差不多,就是变成 git merge --continue
整理历史记录
如果你追求特别高,这也是一个可以卷的地方。git rebase
的功能好像很强大,我们刚刚只是被迫用了一下
这么会有这么复杂的东西,瘫
其他
git commit
的时候怎么写日志,肯定不是至少不应该是xxxxxx
- 同步 fork 的上游仓库
git fetch upstream
# git diff upstream/master HEAD
git checkout master
git merge upstream/master