Git 是 Linux 之父 Linus 的杰作,是如今业界知名度最高、应用最广泛的版本控制系统。说来惭愧,我接触 Git 和 GitHub 已经快两年了,直到今天还只会最常用的几种操作,每当要处理稍复杂的情况都得再百度,而遇到时间线分叉时要么强推要么外部手改达成一致,实属拉胯。最近开始实习,在项目代码仓库里 PR、MR 都不利索,才决定翻出这门吃灰许久的实践课程好好学习一下。
实验 1 Git 与 GitHub 简介
Linux 之父 Linus 在 1991 年创建开源的 Linux 操作系统之后,多年来依靠全世界广大热心志愿者的共同建设,经过长足发展,现已成为世界上最大的服务器系统。系统创建之初,代码贡献者将源码文件发送给 Linus,由其手动合并。这种方式维持多年后,代码量已经庞大到人工合并难以为继,于是深恶集中式版本控制系统的 Linus 选择了一个分布式商业版本控制系统 BitKeeper,不过 Linux 社区的建设者们可以免费使用它。BitKeeper 改变了 Linus 对版本控制的认识,同时 Linus 发现 BitKeeper 有一些不足,而且有个关键性的问题使之不能被广泛使用,就是不开源。
在 2005 年,BitKeeper 所在公司发现 Linux 社区有人企图破解它,BitKeeper 决定收回 Linux 社区的免费使用权。Linus 对此事调解数周无果,找遍了当时已知的各种版本控制系统,没有一个看上眼的,一怒之下决定自己搞一个。Linus 花了十天时间用 C 语言写好了一个开源的版本控制系统,就是著名的 Git。
2007 年旧金山三个年轻人觉得 Git 是个好东西,就搞了一个公司名字叫 GitHub,第二年上线了使用 Ruby 编写的同名网站 GitHub,这是一个基于 Git 的免费代码托管网站(有付费服务)。十年间,该网站迅速蹿红,击败了实力雄厚的 Google Code,成为全世界最受欢迎的代码托管网站。2018 年 6 月,GitHub 被财大气粗的 Microsoft 收购。2019 年 1 月 GitHub 宣布用户可以免费创建私有仓库。根据 2018 年 10 月的 GitHub 年度报告显示,目前有 3100 万开发者创建了 9600 万个项目仓库,有 210 万企业入驻。
有关使用 GitHub 创建仓库、安装 / 更新 Git、使用 Git 克隆远程仓库到本地等内容略
实验 2 Git 基础操作
Git 仓库的三大区域
Git 本地仓库有三大区域:工作区、暂存区、版本区。
修改、提交、推送操作
执行 git status
命令查看整个仓库的状态
执行 git add [文件名]
命令跟踪文件,即把有变动的文件添加到暂存区
执行 git add .
命令把当前目录下的所有变动添加到暂存区
执行 git reset -- [文件名]
或者 git rm --cached [文件名]
命令撤销暂存区的修改
执行 git reset --
命令把暂存区的全部修改撤销
执行 git diff
命令查看工作区被跟踪的文件的修改详情,注意只有在版本区中存在的文件才是被跟踪文件
执行 git diff --cached
命令查看暂存区的全部修改
执行 git commit
命令把暂存区的修改提交到版本区,生成一个新的版本
执行 git log
命令查看版本区的提交历史记录
git log [分支名]
查看某分支的提交历史,不写分支名查看当前所在分支git log --oneline
一行显示提交历史git log -n
其中 n 是数字,查看最近 n 个提交git log --author [贡献者名字]
查看指定贡献者的提交记录git log --graph
图示法显示提交历史
配置个人信息
user.email
:写入你自己注册 GitHub 账号的邮箱user.name
:你自己的 GitHub 账号名字
git config --global user.email "904854724@qq.com"
git config --global user.name "Singularity0909"
默认写入在 ~/.gitconfig
执行 git config -l
命令查看配置信息
执行 git commit
命令生成一个新的提交,一个必须的选项 -m
用来提供该提交的备注
执行 git branch -avv
命令查看全部分支信息
执行 git push
命令,如果后面不带任何选项和参数会把本地仓库当前分支上的新增提交推送到远程仓库的同名分支上
版本回退
执行 git reset --soft HEAD^
命令撤销最近的一次提交,将修改还原到暂存区,--soft
表示软退回,对应的还有 --hard
硬退回,HEAD^
表示撤销一次提交,HEAD^^
表示撤销两次提交,撤销 n 次可以简写为 HEAD~n
执行 git push -f
命令将本地当前分支强行推送到远程仓库同名分支,-f
是 --force
的简写
本地仓库 commit 变化记录
执行 git reflog
命令查看本地仓库所有分支的每一次版本变化
执行 git reset --hard [版本号]
或 git reset --hard HEAD@{id}
命令强行回退到对应提交之前的版本
实验 3 Git 分支操作
添加 SSH 关联授权
ssh-keygen
复制 ~/.ssh/id_rsa.pub
公钥内容,然后 GitHub Settings - SSH and GPG keys - New SSH key,粘贴之后添加 SSH Key 即可。此后如果通过 SSH(非默认 HTTPS)协议同步 Git 仓库就不用再输入密码啦,并且还能提高数据传输速度~
为 Git 命令设置别名
git config --global alias.st status
git config --global alias.br 'branch -avv'
git config --global alias.com 'commit -m'
git config --global alias.ch checkout
Git 分支管理
执行 git fetch
命令刷新保存在本地仓库的远程分支信息
执行 git pull
命令拉取远程仓库分支到本地
执行 git rebase origin/master
命令使本地仓库的当前分支基于远程 origin
仓库的 master
分支
执行 git branch [分支名]
命令创建新的分支
执行 git checkout [分支名]
命令切换分支
执行 git checkout -b [分支名]
命令创建分支并切换到新分支
执行 git push [主机名] [本地分支名]:[远程分支名]
命令将本地分支推送到远程仓库的分支中,通常冒号前后的分支名是相同的,如果是相同的,可以省略 :[远程分支名]
,如果远程分支不存在,会自动创建
执行 git branch -u [主机名/远程分支名] [本地分支名]
命令将本地分支与远程分支关联,或者说使本地分支跟踪远程分支,如果是设置当前所在分支跟踪远程分支,最后一个参数本地分支名可以省略不写, -u
选项是 --set-upstream
的缩写
执行 git branch --unset-upstream [分支名]
命令撤销该分支对远程分支的跟踪,同样地如果撤销当前所在的分支的跟踪,分支名可以省略不写
执行 git push [主机名] :[远程分支名]
或 git push [主机名] --delete [远程分支名]
命令可以在任意本地分支中删除远程分支,原理是将空分支推送到远程分支,结果自然就是远程分支被删除
执行 git push [主机名] :[远程分支名] :[远程分支名] :[远程分支名]
命令一次性删除多个远程分支
执行 git branch -D [分支名]
命令删除本地分支
执行 git branch -m [原分支名] [新分支名]
命令给本地分支改名,若修改当前所在分支的名字,原分支名可以省略不写
实验 4 多人协作 GitHub 部分
略
实验 5 多人协作 Git 部分
如果在组长仓库执行的 commit 备注信息出现 fix #id
,仓库中编号为 #id
的 issue 就会被自动关闭。类似的字样还有 fixes
、fixed
、closes
、close
、closed
。
怎么把修改从组员的仓库添加到组长的仓库呢?这就用到了 pull request 方法,简称 PR。这个词组比较费解,两个词都有动词属性,字面意思是 “拉,请求”,可以理解为这是一个名词性词组,意为 “允许被拉取的请求”。创建一个 PR 就是从甲分支向乙分支提一个请求,该请求中有一个或多个提交,对方觉得可以、没问题,就合并(merge) 这个请求,也就是把请求中所有提交的修改增加到乙分支上,整个过程简称 “提 PR”、“检查合并 PR”。提 PR 既可以在仓库内,也可以跨用户跨仓库。
作为组员,要时刻保持自己的 master 分支与组长的一致,以避免在下次提 PR 时出现冲突,该操作叫做 “同步主仓库”,组长的仓库就是主仓库。在 fork 组长的仓库之后,执行 git remote add [主机名] [主仓库的地址]
命令增加一个关联主机,注意主仓库的地址需要使用 https 开头的。主机名是随意定义的,只要不是 origin 就可以,因为自己的仓库地址对应的主机名是 origin,主仓库的主机名通常定义为 up 或 upstream,这个主机名其实就是一个变量,它的值就是仓库地址,例如 git push origin master
完全等于 git push git@github.com:username/reponame master
。
如何同步主仓库呢?方法有二,一是执行 git pull --rebase up master
,二是执行 git fech up
和 git rebase up/master
。总结一下:git pull --rebase
= git fetch
+ git rebase
。
实验 6 Git tag 和 GitHub releases
略
特别推荐 Sublime Text + Sublime Merge 组合替代 VSCode