跳转至

2023-03 Git操作及程序控制

内容梗概

本课是 2023 年的一次线下课,前半节集中解决同学们在提交第一次作业时遇到的 Git 问题:老师逐一讲解了四类典型报错的成因与排查思路(校园网/VPN 与代理导致的重定向、SSH 协议被禁用、GitLab 分支保护导致无法 push、HTTPS 证书错误),并澄清了 Git for Windows 与 TortoiseGit(小乌龟)的关系。后半节回到 Python 课程内容,围绕"程序结构"一章快速讲解了布尔逻辑、分支、循环、range、函数参数默认值、pass 占位符、关键字参数调用、可变参数与 lambda 匿名函数等知识点,并顺带演示了如何查阅第三方库官方文档以及 GitHub Copilot 的使用。课上还说明了作业安排:第一次作业(编码解码/"表白"作业)因 Git 问题延期一周,下节课讲解答案并布置第二次作业。

知识点详解

一、Git 作业提交的四类典型报错(约 00:00 – 38:00)

1. 网络问题:VPN 与系统代理(约 01:30 – 09:10)

提交/克隆仓库前的第一件事:

  • 确认已连接校园 VPN 或已在校园网中;
  • 关闭所有系统代理,包括在 Git 中设置的代理(如 Clash 等代理工具的全局模式)。

典型现象与判断方法(约 07:00):克隆时报错信息中出现 redirect 重定向到 sso 相关地址。原因是学校设有**单点登录(SSO)机制**:在校外访问任何校内网页都会被重定向到统一身份认证登录页。观察 URL 可以看出机制:登录网址后 ?service= 参数里是被访问的实际服务地址(URL 编码,%3A 是冒号、%2F 是斜杠的编码),登录成功后再跳回。

要点:这个错误与密码、仓库都无关,纯粹是网络不对。即使登了 VPN,若开着全局系统代理,流量仍会经代理绕到外网再绕回来,同样会触发重定向。

2. SSH 协议被禁用:校内 GitLab 只支持 HTTPS(约 11:35 – 16:40)

  • 以往教过的克隆地址是 SSH 协议形式:git@域名:命名空间/仓库名.git。
  • 校内 GitLab 出于安全考虑**关闭了 SSH**:SSH 本质是远程登录协议,拿到终端后可执行 reboot、rm -rf / 等任意操作,危害性大。因此只能用 HTTPS 形式的地址:https://域名/组名/仓库名.git。
  • 需要把地址中的 token、命名空间(group / namespace,一个 group 就是一个命名空间)、仓库名替换为自己的内容。有的仓库有父子两级 group(如 CCS/python-2023/仓库名),有两个命名空间。
  • 若误用 SSH 地址会连接失败:因为协议不同走的端口不同——HTTP/HTTPS 走 80/443 端口,服务器开着;而 SSH 默认端口是 22,服务器没开就直接报网络错误。注意区分:认证失败(密码错)与连接失败(端口没开)是两种不同的错误。

3. GitLab 分支保护导致 push 失败(约 17:00 – 29:20)

典型报错(约 20:40):a default branch main does not yet exist for xxx,提示找 project 的 owner 或 maintainer 创建默认分支,最后 remote rejected ... fail。

成因链条:

  • GitLab 用户在组/仓库中有五级权限:Owner > Maintainer > Developer > Reporter > Guest。Owner 如老板、Maintainer 如项目经理、Developer 是普通开发者、Reporter 给测试人员、Guest 只能看不能改。同学们都被分配为 Developer。
  • GitLab 有**分支保护(protected branches)机制**(Settings 中的 default branch 设置),本质是防止任何人随意往 main 等主分支 push 代码(防止恶意或失误覆盖代码,尤其配合强制删除历史版本就更危险)。
  • 创建仓库时的默认保护级别是"完全保护":developers cannot push new commits, but maintainers can, no one can force push。
  • 因此出现死循环:Developer 创建仓库时无权限初始化 main 分支 → 仓库没有任何分支 → push 时既无默认分支也无提交权限 → 报错。

解决办法(老师已把组内默认分支保护设置改宽):

  1. 删掉原来的空仓库重建一个,GitLab 会自动创建 main 分支,可正常 push;
  2. 或在原空仓库基础上先 push 一个 main 分支,再 push 一个 0x01 分支(操作两次)。

4. HTTPS 证书错误(约 29:20 – 36:00)

  • 报错中出现 custom ... not found,即 Git 找不到本地的认证证书,无法完成 HTTPS 连接建立。
  • 原理背景:HTTPS 通信需要本地与服务器双方通过数字证书/数字签名交换来建立可靠、保密的连接(属密码学/计算机网络内容,可自行了解 HTTPS 通信过程)。
  • 老师的推断(未验证):报错信息中证书路径出现乱码,可能是 Git for Windows 安装在中文路径下导致找不到证书。建议方案:重装 Git for Windows 到**英文路径**下。老师明确表示这只是推断,不作结论。

5. Git for Windows 与 TortoiseGit 的区别(约 36:00 – 38:00)

  • Git for Windows:命令行工具,装完后命令行可识别 git 命令,右键菜单多出 Open Git GUI here 和 Open Git Bash here;本身没有可视化的克隆/提交界面,克隆要在 Git Bash 中敲 git clone。
  • TortoiseGit(小乌龟):只提供图形界面。点 OK 的瞬间,它把界面上填的参数拼成命令行,再去调用 Git for Windows 执行。因此**只装小乌龟没装 Git for Windows 会报错**(拼好命令后找不到 git),两者都装才能正常工作。
  • 判断该重装哪个:看报错中的路径——路径是 Git-... 则是 Git for Windows 的问题,是 TortoiseGit-... 则是小乌龟的问题。

二、作业与学习安排(约 38:00 – 44:50)

  • 第一次作业是编码解码("表白")程序,因很多人被 Git 卡住,截止日期延到下周,下节课讲答案并点评大家的作业。
  • 老师要求以后每次课前明确预习范围:做第一次作业前应看完"运行方式/交互环境"及"数字数据类型"至少到"类型转换";下次课(布置第二次作业)之前务必看完"程序结构"相关的全部视频(分支、循环、函数等,与 C 语言相通)。

三、布尔逻辑与真值检测(约 45:20 – 47:20)

  • 布尔逻辑是分支和循环的前提:必须有判断是否执行分支/继续循环的真值。
  • Python 中为 False 的值:None、False、整数 0、浮点数 0.0、空字符串、空元组、空列表、空迭代器等。
  • 逻辑运算符与 C 语言基本一致;特殊的是 is 和 is not:类似"等于/不等于",但比较的是对象身份,常用于判断 xxx is None(是否是空对象),可读性像英文。

四、分支与循环(约 47:20 – 51:20)

  • 分支结构与 C 语言一致;注意多分支关键字是 elif,不是 else if。
  • for 循环与 C 语言最大的不同:for 变量 in 序列,可对任何序列(字符串、列表、元组,以后学的字典等)直接遍历,对常见工作流非常友善。
  • 课件示例:对 numbers 列表遍历,判断奇偶并分别 append 到两个空列表。用 C 语言写需自行分配内存(malloc 等),Python 直接用列表即可。

五、range(约 49:00 – 51:20)

  • range 是内置函数(官方文档称其为内置函数,但更像一个不可变序列类型),用于生成从 start 到 stop(取不到 stop)、步长为 step 的一系列值,循环中最常用。
  • range(8) 等价于 range(0, 8),生成 0–7;range(0, 10, 2) 中第三个参数是步长 step。
  • 不写 step 时默认值为 1——由此引出 Python 函数**参数默认值**的概念(C 语言中除 printf 变长参数外没有默认值概念,在 Python 里是很基础的知识)。

六、break / continue / else 与 pass(约 55:20 – 58:20)

  • break、continue、循环的 else 与 C 语言用法"一模一样",不赘述。
  • pass 是 Python 特有的占位符:代码块(冒号后)不能为空,否则语法检查报错;没想好函数/循环体怎么写时先放 pass 占位,保证语法正确、程序框架完整,具体实现留给以后(或协作者)。大型项目、面向对象中常用 pass 预留函数接口。

七、函数参数(约 58:20 – 01:08:20)

  • 函数定义、递归(斐波那契数列)与 C 语言相同,看视频即可。
  • 参数默认值:定义时写 step=1 即声明可选参数,调用时可省略。必须先写完所有必选参数才能写可选参数;一旦出现带缺省值的参数,其后所有参数都必须有缺省值(老师现场用 test(argument1, argument2, argument3=3) 演示:再追加无默认值的 argument4 会报语法错误,补上 =4 或挪到前面即可)。
  • 关键字参数调用:调用时可写 test(1, 2, 3, 4) 按位置传参,也可写 test(argument2=2, argument3=3, ...) 按名字传参。参数多时(如第三方库)按名字写更清晰——以 wordcloud 库为例,其初始化函数参数极多,指定 background_color=... 必须按名传参。
  • 可变参数:用 *x 形式可接收任意个数参数,函数内 x 对应一个列表(老师口述为列表)。示例:拼接函数用字符串的 join 方法把列表用指定分隔符(如 \t 制表符,可改成分号等)拼成一个字符串。
  • lambda 匿名函数:lambda p: p[1] 等价于定义一个输入为 p、返回 p[1] 的无名函数。冒号前是参数(输入),冒号后是返回值(输出)。典型用途:list.sort(key=lambda p: p[1])——sort 的 key 参数接收一个函数作为排序依据,示例为对元组列表按每个元组的第 1 项(索引 1,即第二项,第 0 项是第一个数字)排序。这种让程序员"偷懒尝到甜头"、对功能无影响的写法叫**语法糖**。

八、工具与学习方法(约 01:02:40 – 01:12:30)

  • 查官方文档的套路:关键词搜到官网 → 找文档 → 大库一般先看 quick start / getting started 示例 → 再查 API reference(函数手册);以 requests 库文档为典型。强调学计算机要学好英文,直接看一手官方资料,避免二手资料引入错误。
  • GitHub Copilot:VS Code 插件,可自动补全代码(写注释后等待即补全实现,按 Tab 接受),还带聊天功能可让它修复代码问题。学生/教师可通过 GitHub 教育认证免费申请,支持 Python、Java、C 等多种语言。老师推荐使用,但提醒:作业中要求自己手写、不允许直接生成;且 Copilot 生成的代码可能有小 bug,必须懂程序才能修正——"写代码一小时,调代码七小时"。

示例与演示

  • SSO 重定向演示(约 07:00):展示同学克隆失败的截图,从报错中的 redirect ... sso 字样推断未连校园网;并现场演示退出校园网登录后访问校内网页被重定向到统一身份认证页。
  • HTTPS 地址拼接演示(约 13:00):以自己仓库为例说明 URL 结构:https://域名/组名/仓库名.git,token、命名空间、仓库名都要替换;演示了 CCS(父 group)/ python-2023(子 group)两级命名空间的情况。
  • SSH 克隆报错演示(约 15:00):误用 SSH 地址克隆报连接失败,因 22 端口未开放。
  • 分支保护机制演示(约 24:00):打开 GitLab 仓库设置的 default branch 保护选项,展示"developers cannot push new commits, but maintainers can, no one can force push"的完全保护状态及修改后的状态;展示无 main 分支的空仓库。
  • 参数默认值演示(约 59:00):在 VS Code 中定义 def test(argument1, argument2, argument3=3): pass,演示在必选参数后再加无默认值参数会画波浪线报错。
  • join 拼接演示(约 01:13:30):可变参数拼接函数,用 \t(制表符)为分隔符把 "安静", "ABC", "DEF" 等拼接打印,改分隔符为分号后结果相应变化。
  • lambda 排序演示(约 01:16:00):对含 4 个元组(形如 (数字, 数字))的列表用 sort(key=lambda p: p[1]) 按第二项排序并 print 输出。
  • Copilot 演示(约 01:09:20):写一行注释后等待 Copilot 自动补全一个编码函数的实现,按 Tab 接受;演示用 Copilot Chat 让它 fix 代码问题。
  • 作业说明:第一次作业为编码解码("表白")程序,老师给了带 pass 占位的框架代码 demo.py,删掉 pass 会被语法检查器标错;作业延期至下周,下节课讲答案。第二次作业下节课布置,课前需看完"程序结构"全部视频。

重点与难点

  • 会读报错才算计算机入门(老师反复强调):要从报错信息反推原因——重定向到 SSO → 网络/VPN/代理问题;连接失败 → 端口/协议问题;认证失败 → 密码问题;路径乱码 → 中文路径问题。
  • VPN 与代理不能共存:登了 VPN 又开全局代理,流量仍绕外网,照样报错;Git 中单独设置的代理也要关闭。
  • SSH 默认端口 22 是常识,校内 GitLab 已禁用 SSH,只能用 HTTPS 地址。
  • **GitLab 分支保护机制**是本次 push 失败的根因:Developer 权限在完全保护下无法创建/推送默认分支。理解五级权限(Owner/Maintainer/Developer/Reporter/Guest)的用途。
  • 小乌龟 ≠ Git:TortoiseGit 只是壳,实际执行靠 Git for Windows,两个都要装;判断重装哪个看报错路径前缀。
  • Python 易错点:elif 不是 else if;range 取不到 stop 值;代码块不能为空、用 pass 占位;必选参数不能放在带默认值的参数之后。
  • 课前预习要求:下次课前看完"程序结构"全部视频,不要只看本课讲的几个"特别点"而跳过前面内容。

关联内容

  • 本课承接上一课布置的第一次作业(编码解码/"表白"程序),作业答案与点评在下一次课(2023 年下一次线下课)讲解,同时布置第二次作业。
  • Git 部分与之前教过的 SSH 克隆方式(git@域名:命名空间/仓库名.git)衔接,说明校内 GitLab 改用 HTTPS 的原因;后续六次作业都要用这套 Git 流程提交,故本课花整节课解决。
  • 预习内容关联课程前面章节:"运行方式/交互环境""数字数据类型"(至少到"类型转换")是第一次作业的前置知识;"程序结构"(分支、循环、函数)是第二次作业的前置知识。
  • 知识点上大量对照 C 语言(学生已有 C 语言基础):布尔逻辑、分支、break/continue、函数与递归与 C 一致;for...in、range、参数默认值、pass、lambda 是 Python 特有或显著不同之处。参数默认值、可变参数、lambda 与后面章节的"函数"部分、面向对象内容相关联。
  • HTTPS 证书、数字签名原理属"密码学/计算机网络"课程的内容;is/is not 涉及对象身份,与后续对象概念相关。