391 lines
14 KiB
Markdown
391 lines
14 KiB
Markdown
# 3.5git 与 github
|
||
|
||
引自 nju-ics-pa
|
||
|
||
## <strong>光玉</strong>
|
||
|
||
想象一下你正在玩 Flappy Bird ,你今晚的目标是拿到 100 分,不然就不睡觉。 经过千辛万苦,你拿到了 99 分,就要看到成功的曙光的时候,你竟然失手了!你悲痛欲绝,滴血的心在呼喊着,“为什么上天要这样折磨我?为什么不让我存档?”
|
||
|
||
想象一下你正在写代码,你今晚的目标是实现某一个新功能,不然就不睡觉。经过千辛万苦,你终于把代码写好了,保存并编译运行,你看到调试信息一行一行地在终端上输出。就要看到成功的曙光的时候,竟然发生了错误!你仔细思考,发现你之前的构思有着致命的错误,但之前正确运行的代码已经永远离你而去了。你悲痛欲绝,滴血的心在呼喊着,“为什么上天要这样折磨我?”你绝望地倒在屏幕前 ... ... 这时,你发现身边渐渐出现无数的光玉,把你包围起来,耀眼的光芒令你无法睁开眼睛 ... ... 等到你回过神来,你发现屏幕上正是那份之前正确运行的代码!但在你的记忆中,你确实经历过那悲痛欲绝的时刻 ... ... 这一切真是不可思议啊 ... ...
|
||
|
||
## <strong>人生如戏</strong><strong>,</strong><strong>戏如人生</strong>
|
||
|
||
人生就像不能重玩的 Flappy Bird,但软件工程领域却并非如此,而那不可思议的光玉就是“版本控制系统”。版本控制系统给你的开发流程提供了比朋也收集的更强大的光玉,能够让你在过去和未来中随意穿梭,避免上文中的悲剧降临你的身上。
|
||
|
||
没听说过版本控制系统就完成实验,艰辛地排除万难,就像游戏通关之后才知道原来游戏可以存档一样,其实玩游戏的时候进行存档并不是什么丢人的事情。
|
||
|
||
在本节,我们使用 `git` 进行版本控制。下面简单介绍如何使用 `git` :
|
||
|
||
### <strong>游戏设置</strong>
|
||
|
||
首先你得安装 `git` :
|
||
|
||
- Linux 下
|
||
|
||
```
|
||
# Debian , Ubuntu
|
||
sudo apt install git
|
||
```
|
||
|
||
- windows 下
|
||
|
||
从这里下载 [https://git-scm.com/download/win](https://git-scm.com/download/win)
|
||
|
||
下载完安装一路点 `next` 就行,什么配置也不用动。
|
||
|
||
安装好之后,你需要先进行一些配置工作。在终端里输入以下命令:
|
||
|
||
```
|
||
git config --global user.name "Zhang San" # your name
|
||
git config --global user.email "zhangsan@foo.com" # your email
|
||
```
|
||
|
||
经过这些配置, 你就可以开始使用 `git` 了。
|
||
|
||
你会通过 `git clone` 命令来拉取远程仓库的代码,里面已经包含一些 `git` 记录,因此不需要额外进行初始化。如果你想在别的实验、项目中使用 `git` ,你首先需要切换到实验、项目的目录中,然后输入
|
||
|
||
```
|
||
git init
|
||
```
|
||
|
||
进行初始化。初始化后会创建一个隐藏的文件夹名为 `.git` git 会基于这个文件夹来进行版本控制功能。
|
||
|
||
### <strong>查看</strong><strong>commit</strong><strong>信息</strong>
|
||
|
||
使用
|
||
|
||
```
|
||
git log
|
||
```
|
||
|
||
查看目前为止所有的 commit 记录。
|
||
|
||
(commit:提交)
|
||
|
||
使用
|
||
|
||
```
|
||
git status
|
||
```
|
||
|
||
可以得知,与当前存档相比,哪些文件发生了变化.
|
||
|
||
### 提交
|
||
|
||
你可以像以前一样编写代码。等到你的开发取得了一些阶段性成果,你应该马上进行 “ 提交( commit )”。
|
||
|
||
首先你需要使用 `git status` 查看是否有新的文件或已修改的文件未被跟踪;若有,则使用 `git add` 将文件加入跟踪列表,例如
|
||
|
||
```
|
||
git add file.c
|
||
```
|
||
|
||
会将 `file.c` 加入跟踪列表。如果需要一次添加所有未被跟踪的文件,你可以使用
|
||
|
||
```
|
||
git add -A
|
||
# or
|
||
git add .
|
||
```
|
||
|
||
但这样可能会跟踪了一些不必要的文件(二进制文件),例如编译产生的 `.o` 文件,和最后产生的可执行文件。事实上,我们只需要跟踪代码源文件即可。为了让 `git` 在添加跟踪文件之前作筛选,你可以编辑 `.gitignore` 文件( 没有的话手动创建 文件名就叫这个 ),在里面给出需要被 `git` 忽略的文件和文件类型。
|
||
|
||
这个网页可以根据你搜索的语言来给你创建必要的 `.gitignore` 文件
|
||
|
||
```
|
||
# .gitignore文件示例
|
||
.idea # 编辑器配置
|
||
__pycache__ # 缓存文件夹
|
||
node_modules # 某个可以拉取的模块文件夹
|
||
dist
|
||
*.local # 以.local为后缀的文件
|
||
index.html # 一个文件
|
||
file.o # 一个编译后的文件
|
||
```
|
||
|
||
建议把编译后的文件都加入 `.gitignore` 并在 `README.md` 文件中留下编译的详细操作流程,节省 `.git` 空间、符合提交规范。
|
||
|
||
把新文件加入跟踪列表后, 使用 `git status` 再次确认. 确认无误后就可以存档了, 使用
|
||
|
||
```
|
||
git commit -m "...comment..."
|
||
```
|
||
|
||
提交工程当前的状态(注释)。其中 `...comment...` 是你本次提交的注释( 一般在注释中简略写出本次提交干了什么)以下为注释规范,养成良好习惯请遵守:
|
||
|
||
```
|
||
模板:
|
||
type(scope): subject
|
||
|
||
type为commit的类型
|
||
feat: 新特性
|
||
fix: 修改问题
|
||
refactor: 代码重构
|
||
docs: 文档修改
|
||
style: 代码格式修改
|
||
test: 测试用例修改
|
||
chore: 其他修改, 比如构建流程, 依赖管理.
|
||
pref: 性能提升的修改
|
||
build: 对项目构建或者依赖的改动
|
||
ci: CI 的修改(ci是自动构建 感兴趣可以搜搜 github workflow )
|
||
revert: revert 前一个 commit ( 撤销前一个commit )
|
||
|
||
scope是文件名/模块名/影响的范围
|
||
例如 schoolSchedule
|
||
|
||
subject为commit概述
|
||
建议符合 50/72 formatting
|
||
|
||
例 feat(JoinForm): add success submit tips
|
||
|
||
注意 冒号和subject之间要加空格
|
||
```
|
||
|
||
你可以使用 `git log` 查看存档记录,你应该能看到刚才编辑的注释。
|
||
|
||
### <strong>读档</strong><strong>( 回溯到某一个 commit )</strong>
|
||
|
||
如果你遇到了上文提到的让你悲痛欲绝的情况,现在你可以使用光玉来救你一命了。首先使用 `git log` 来查看已有的存档,并决定你需要回到哪个过去。每一份存档都有一个 `hash code`,例如 `b87c512d10348fd8f1e32ddea8ec95f87215aaa5` , 你需要通过 `hash code` 来告诉 `git` 你希望读哪一个档。使用以下命令进行读档:
|
||
|
||
```
|
||
git reset --hard b87c
|
||
```
|
||
|
||
其中 `b87c` 是上文 `hash code` 的前缀:你不需要输入整个 hash code. 这时你再看看你的代码,你已经成功地回到了过去!
|
||
|
||
但事实上, 在使用 `git reset` 的 `hard` 模式之前, 你需要再三确认选择的存档是不是你的真正目标。 如果你读入了一个较早的存档,那么比这个存档新的所有记录都将被删除!这意味着你不能随便回到“将来”了。
|
||
|
||
### 分支
|
||
|
||
当然还是有办法来避免上文提到的副作用的,这就是 `git` 的分支功能。使用命令:
|
||
|
||
```
|
||
git branch
|
||
```
|
||
|
||
查看所有分支. 其中 `master` 是主分支,使用 `git init` 初始化之后会自动建立主分支。
|
||
|
||
读档的时候使用以下命令:
|
||
|
||
```
|
||
git checkout b87c
|
||
```
|
||
|
||
而不是 `git reset` 。这时你将处于一个虚构的分支中,你可以
|
||
|
||
- 查看 `b87c` 存档的内容
|
||
- 使用以下命令切换到其它分支
|
||
|
||
```
|
||
git checkout 分支名
|
||
```
|
||
|
||
- 对代码的内容进行修改,但你不能使用 `git commit` 进行存档,你需要使用
|
||
|
||
```
|
||
git checkout -B 分支名
|
||
```
|
||
|
||
- 把修改结果保存到一个新的分支中,如果分支已存在,其内容将会被覆盖
|
||
|
||
不同的分支之间不会相互干扰,这也给项目的分布式开发带来了便利。有了分支功能,你就可以像第三视点那样在一个世界的不同时间 ( 一个分支的多个存档 ),或者是多个平行世界 ( 多个分支 ) 之间来回穿梭了。
|
||
|
||
### <strong>更多功能</strong>
|
||
|
||
以上介绍的是 `git` 的一些基本功能,`git` 还提供很多强大的功能,例如使用 `git diff` 比较同一个文件在不同版本中的区别,使用 `git bisect` 进行二分搜索来寻找一个 bug 在哪次提交中被引入...
|
||
|
||
其它功能的使用请参考 `git help` , `man git` , 或者在网上搜索相关资料。
|
||
|
||
## 全球最大男性交友网站 —— Github
|
||
|
||
简介
|
||
|
||
作为开源代码库以及版本控制系统,Github 拥有超过 900 万开发者用户。随着越来越多的应用程序转移到了云上,Github 已经成为了管理软件开发以及发现已有代码的首选方法。
|
||
|
||
页面大概是这样:
|
||
|
||

|
||
|
||
### Git 和 Github
|
||
|
||
[GitHub](https://github.com/)[ ](https://github.com/)是一个面向开源及私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub。
|
||
|
||
### Git 绑定 Github
|
||
|
||
#### 第一步:注册账号
|
||
|
||
([GitHub 官网](https://github.com/))右上角 sign up 会有一个非常酷炫的界面指引你注册 🥳
|
||
|
||
#### 第二步:创建 SSH Key 并获取公钥
|
||
|
||
先在 C:\Users\用户名\.ssh 下找有没有 `id_rsa` 和 `id_rsa.pub` 文件
|
||
|
||
如果有就直接跳过这一步
|
||
|
||
如果没有,打开 Shell( Windows 下打开 Git Bash <em>前提是你已经安装好了 git 在桌面右键应该会有 Git bash here 选项 </em>),创建 SSH Key:
|
||
|
||
```powershell
|
||
ssh-keygen -t rsa -C "youremail@example.com" # youremail为你注册用的电子邮件地址
|
||
```
|
||
|
||
打开 `id_rsa.pub`,复制里面的内容
|
||
|
||
#### 第三步:绑定 Github
|
||
|
||
登陆 `GitHub`,打开 `settings`
|
||
|
||

|
||
|
||
然后打开左侧栏 `SSH and GPG`` keys` 页面
|
||
|
||

|
||
|
||
然后,点 `New SSH Key`,填上任意 Title,在 Key 文本框里粘贴 `id_rsa.pub` 文件的内容即可
|
||
|
||
#### 第四步:创建仓库并和本地绑定
|
||
|
||
绑定完 GitHub 然后你可以创建仓库了
|
||
首先在 GitHub 主页,找到 “New” 按钮,创建一个新的仓库
|
||
|
||

|
||
|
||
然后填上这个仓库的大名就可以创建了
|
||
|
||

|
||
|
||
根据之前学习的方法在本地创建完 git 仓库之后
|
||
|
||
在 git bash 中输入:
|
||
|
||
```powershell
|
||
git remote add origin git@github.com:yourname/gitexample.git
|
||
# 请将yourname换成自己的id
|
||
```
|
||
|
||
就可以绑定
|
||
|
||
或者是直接 git clone 下来
|
||
|
||
```powershell
|
||
git clone git@github.com:yourname/gitexample.git
|
||
```
|
||
|
||
### 下载代码——clone
|
||
|
||
拷贝他人存档也未尝不可,而我们如果用他人存档时,次次都需要一样一样的拷贝文件和代码未免太过折磨,下面简单介绍如何使用
|
||
|
||
```powershell
|
||
git clone [url]
|
||
```
|
||
|
||
接下去对着下面这个 GitHub 的代码使用一下
|
||
|
||
首先,代码的 url 在下图所示的位置
|
||
|
||

|
||
|
||
然后复制完代码后切换回我们的命令行
|
||
|
||
```bash
|
||
e: #powershell or cmd
|
||
# 进入到想要存储该代码的地方
|
||
git clone https://github.com/camera-2018/git-example.git
|
||
```
|
||
|
||
一阵抽搐过后就下载好了
|
||
|
||

|
||
|
||
注意:用完之后别忘记给 camera-2018 点个 follow 呃呃 follow 没用 star 有用
|
||
|
||
注意:失败就重试吧 还失败建议使用魔法
|
||
|
||
### 提交和合并分支
|
||
|
||
如图 我在仓库里新建了 `helloworld.c` 并且写了一些代码
|
||
|
||

|
||
|
||
接下来是提交操作
|
||
|
||
```bash
|
||
git status #看一下文件暂存区
|
||
```
|
||
|
||

|
||
|
||
红色表示文件没有提交到暂存区 我们要提交
|
||
|
||
接下来
|
||
|
||
```bash
|
||
git add . #将没有提交的所有文件加入暂存区
|
||
```
|
||
|
||

|
||
|
||
绿色表示所有文件已加入暂存
|
||
|
||
```bash
|
||
git commit -m "feat(helloworld): add helloworld file"
|
||
```
|
||
|
||
将刚才加入暂区的文件发起了一个提交 注释是 `feat(helloworld): add helloworld file`
|
||
|
||

|
||
|
||
1. 如果这是你自己的仓库有权限 你就可以直接使用
|
||
|
||
```bash
|
||
git push origin main # origin是第四步里remote add起的远程名字
|
||
# main是分支名
|
||
```
|
||
|
||
上传本次提交
|
||
|
||

|
||
|
||
1. 如果你没有本仓库的主分支提交权限 可以提交 pr(pull requests)
|
||
|
||
这里假设我是协作者 无主分支权限
|
||
|
||
首先创建一个新分支 命名为 `yourname-dev`
|
||
|
||

|
||
|
||
然后按照上面的方法 `git clone` 并切换到你刚创建的分支
|
||
|
||
```bash
|
||
git switch camera-2018-dev
|
||
```
|
||
|
||
然后提交一个文件 这里使用 vscode 自带的 git 工具试试
|
||
|
||

|
||
|
||
点暂存所有更改 写好 comment 之后点提交
|
||
|
||

|
||
|
||
最后点同步更改上传
|
||
|
||

|
||
|
||
如果是你提交 在 github 上会显示这个 快捷创建 pr 的按钮
|
||
|
||

|
||
|
||

|
||
|
||
点它创建 pr
|
||
|
||

|
||
|
||
这样管理本仓库的人看到 pr 请求就可以 merge 合并辣
|
||
|
||

|
||
|
||

|
||
|
||
实际合作过程中可能会出现代码冲突无法 merge 的情况 😋 遇到了自己去 STFW 吧
|