一、Git文件的三种状态:
- 已修改【Modified】(Work Directory):已修改表示修改了文件,但还没保存到数据库中
- 使用编辑器修改任意代码
- 已暂存【Staged】(Staging Area):已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中
- 使用
git add $file_name后文件的状态
- 使用
- 已提交【Committed】(Git Directory):已提交表示数据已经安全地保存在本地数据库中
- 使用
git commit -m "$your_comments"后文件的状态

二、一种常用的代码Commit流程
A. 正常提交
查看具体修改的文件列表
1
git status
查看特定文件具体的更改内容,并删除无意义/非必要的修改,缩小单个文件修改影响
1
git diff $file # 查看每个文件具体的修改内容,git会精确到每一行的修改差异
如果整个文件的修改希望被放弃(回退为之前的状态)
1
git restore $file # 此时git status将不会返回该文件
将期望上传的修改提交为
Staged此时对应文件将从
Modified状态变为Staged1
git add $file_path $file_fold # 支持terminal通配符
重复1~3步,所有必要的修改被提交为Staged状态,确保依旧保持Modified状态的文件为非运行时必须的文件
正式提交本次修改内容到仓库
此时Stage状态的修改内容应该描述了一种修改目的,例如:
- 增加并行执行能力
- 修复重复打印的bug
- 增加xxx功能
- 代码风格化
- …
为了方便后续查询更改/版本管理/版本回退/团队协作等,我们应该把这种修改目的跟随修改内容一同提交到仓库。
1
git commit -m "你的修改目的"
此时所有
Staged文件将变为Committed,即正式成为本地Git仓库的一部分。注:实际上,commit提交的时候,除了修改目的,git还会自动打包例如作者、日期等等信息,用于追溯仓库历史变动。
B. 合并提交
1 | git reset --soft $last_remain_commit # commit files set to stage, and other remain itself, cleanup commit to $last_remain_commit |
三、文件忽略
对于单个开发者,有时我们存在一些本地数据,或临时的脚本,甚至程序运行时自动生成的文件(例如python会自动生成__pycache__)。我们不希望将其提交到仓库中。
- 方法一:每次
git add的时候,手动规避这些文件。这可能在不经意间误操作,导致仓库被上传脏数据 - 方法二:通过
.gitignore文件。git会自动忽略.gitignore文件中记录的文件/文件夹,且会自动应用到.gitignore文件所在目录及其子目录,支持通配符
注意:.gitignore文件仅对Modified状态文件生效,即如果文件本身已经在其它状态,则不会生效
.gitignore 示例:
1 | __pycache__/ # 忽略所有__pycache__文件夹 |
注意:.gitignore文件将作为仓库的一部分,未来将对所有协作者产生影响。因此合理选取忽略范围,例如不应该在python项目向.gitignore中添加*.py`
四、基于目录的代码管理
目的:
- 代码模块化,便于协作和阅读
- 有效利用
.gitignore机制,方便git管理代码
五、Git是怎么管理与合并代码(merge)
手动合并代码
1 | git branch # 查看所有分支,*标识的分支为当前分支 |
六、Git本地与远程仓库
本地仓库:用户直接coding的仓库
远程仓库:用户不可直接coding的仓库,通常位于远程,主要用于存储代码
1. 配置远程仓库访问
需要在github配置对应的公钥文件
编辑~/.ssh/config
1 | HOST github.com |
2. 下载远程仓库特定分支
适用于本地没有仓库
1
git clone -b target git@test.github.com:test/test_rep.git # 注意域名变化
适用于本地已经有仓库,但是没有对应的远程分支
1
2
3
4
5
6
7cd test_rep # 本地仓库根目录
git fetch # 拉取远程仓库信息
git switch target # 切换到指定分支,也用于本地不同分支之间切换
git checkout <commit_id> # 如果希望查阅某个commit,但是不向下开发
git checkout -b new_branch_name <commit_id> # 如果希望基于某个commit继续向下开发全新的代码
git reset --hard <commit_id> # 如果希望当前代码回退到某次commit本地已经有远程分支对应的分支
1
2# git branch --set-upstream-to=origin/remote_branch local_branch_name # 可设置远程分支绑定
git pull
3. 向远程仓库上传特定分支
当前分支暂未绑定远程分支,创建绑定并推送
1
git push --set-upstream origin local_branch_name
当前已经绑定远程分支,推送Commit
相当于远程仓库被绑定的分支执行Merge操作,因此开发者应确保本地分支与远程分支无冲突
1
git push
七、基于Git的多人协作
八、基于Git的多组织协作

九、子仓库引用
用于在一个 Git 仓库中嵌套另一个 Git 仓库
添加三方仓库作为子仓库
1
git submodule add xxxxxx.git fold/sub_rep
更新子仓库代码与远程仓库一致
1
2git submodule init # 第一次需要,从远程同步子仓库目录信息
git submodule update # 下载子仓库代码的指定commit到指定目录更新子仓库代码到子仓库的其它版本
1
2
3
4
5
6
7
8cd fold/sub_rep
git pull # 更新commit到最新版本
cd ../..
# 正常提交修改即可
git add fold/sub_rep # 实际上提交的是commit值,而不是具体的修改文件
git commit -m "update fold/sub_rep to latest version"
git push删除子模块
1
2git rm --cached fold/sub_rep
rm -r fold/sub_rep
意义:
管理外部依赖
- 项目包含多个三方库或工具,需要直接包含在你的项目中,以便能够进行修改或使用特定版本。这允许你轻松跟踪和更新这些依赖项的版本
开发多个相关项目
- 当你开发多个相关的项目,其中一个项目依赖于其他项目的代码时,可以将这些项目组织为多个子模块。这种方法可以帮助你将共享代码模块化,并在多个项目中复用
协作开发
- 在大型团队项目中,各个子项目由不同的子团队负责开发和维护
- 各团队开发的组件或插件作为独立的子模块,需要独立的集成和版本控制,以便于适用多个上游项目需求
十、持续集成/持续部署CI/CD【DevOps
这是github等网站提供的一种能力,用于辅助代码规范和正确性
