Git 和 Github 基础教程

学习 Git 和 Github,我主要是跟着 Git 使用教程来做的,文中每一步都有图和解释,超详细,手把手教你使用 Git 和 Github,极力推荐给正在入门的小白!参考该教程、文后的链接和我自己的理解,构成本文的内容。由于目前个人用不到多人协作,因此本文并未提及,如有需要,也请参考 Git 使用教程

此处列出了一些我收藏的公认的比较好的 Git 教程,可以作为深入学习资料

Git 简介

Git 是什么?

Git是目前世界上最先进的分布式版本控制系统。

SVN 与 Git 的最主要的区别?

SVN 是集中式版本控制系统,版本库集中放在中央服务器。干活的时候用自己的电脑,首先要从中央服务器哪里得到最新的版本,然后干活,干完后把自己做完的活推送到中央服务器。集中式版本控制系统必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,就难办了。

Git 是分布式版本控制系统,没有中央服务器。每个人的电脑就是一个完整的版本库,工作的时候不需要联网。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件 A,其他人也在电脑上改了文件 A,这时,你们俩只需把各自的修改推送给对方,就可以互相看到对方的修改了。

安装 Git(Windows)

安装

建议到 Git 官网 下载最新版本,国内访问会很慢,可以到网上搜索下载,然后默认安装即可。安装完成后,在开始菜单里面找到 “Git –> Git Bash”,如下:

"Git --> Git Bash"

弹出一个类似的命令窗口的东西,就说明 Git 安装成功。如下:

"git安装成功"

设置用户名和邮箱

因为 Git 是分布式版本控制系统,所以需要填写用户名和邮箱作为一个标识。在命令行输入如下:

"设置邮箱和用户名"

注意!git config --global 参数,表示你这台机器上所有的 Git 仓库都会使用这个配置,当然你也可以对某个仓库指定的不同的用户名和邮箱。

查看已设置的用户名和邮箱,在命令行输入如下:

"查看邮箱和用户名"

使用Git

创建版本库 repository

版本库:又名仓库,英文名 repository。可简单的理解一个目录,这个目录里面的所有文件都会被 Git 管理,每个文件的修改,删除,Git 都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻还可以将文件“还原”。

命令 释义
打开所在目录
cd folder 打开文件夹
mkdir folder 新建文件夹
pwd 显示当前目录
初始化:将当前目录变为 Git 仓库
git init 当前目录 → git 可管理仓库
添加文件到版本库
git add file 将 file 文件添加到暂存区
git commit -m “提交说明” 将暂存区中所有文件提交到仓库
git status 查看当前目录中是否有文件未提交

打开所在目录

创建一个版本库,如在 D:/www 下 目录下新建一个 testgit 版本库,在命令行输入如下:

"创建版本库"

初始化:将当前目录变为 Git 仓库

"初始化"

注意! 这时当前 testgit 目录下会多一个 .git 的目录,这个目录是 Git 来跟踪管理版本的,千万不要手动乱改这个目录里面的文件,否则,会把 Git 仓库给破坏了。如下:

  • ".git"

添加文件到版本库

作为测试,在当前目录下新建一个 readme.txt,并写入 11111111 保存,之后进行如下3步操作:

"添加文件到版本库"

git status 结果显示没有任何文件未提交。

修改和版本回退

命令 释义
修改文件内容
git diff file 查看 file 文件修改内容
查看历史记录
git log 查看历史记录
git log –pretty=oneline 查看历史记录(简洁版)
版本回退
git reset –hard HEAD^ 退回到上个版本
git reset –hard HEAD^^ 退回到上上个版本
git reset –hard HEAD~100 退回到前100个版本
恢复最新版本
git reflog 获取全部版本号
git reset –hard 版本号 退回到版本号的版本
cat file 查看文件内容

修改文件内容

继续,修改 readme.txt 内容,在下面添加一行 22222222 内容,继续使用 git status 查看结果,如下:

"git status"

结果显示,readme.txt 文件已被修改,但是未被提交的修改。接下来我想看下 readme.txt 文件到底改了什么内容,如何查看呢?可以使用如下命令:

"git diff"

结果显示,readme.txt 文件内容从一行 11111111 改成两行,添加了一行 22222222 内容。

知道了对 readme.txt 文件做了什么修改后,我们可以放心的提交到仓库了,提交修改和提交文件是一样的两步(第一步是 git add 第二步是:git commit)。如下:

"增加222"

git status:提交文件之前,查看一下状态;提交文件之后,继续查看一下状态,显示没有可提交的文件

说明: 所有的版本控制系统,只能跟踪文本文件的改动(如 txt 文件,网页,所有程序的代码等)。对于图片,视频这些二进制文件,只能把每次改动串起来,无法跟踪文件的变化,即:知道图片从 1kb 变成 2kb,但是到底改了什么,版本控制系统也不知道

查看历史记录

继续对 readme.txt 文件进行修改,再增加一行
内容为 33333333,然后执行命令如下:

"增加 333 内容"

现在我已经对 readme.txt 文件做了三次修改了,那么我现在想查看下历史记录,如何查看呢?使用命令 git log ,如下:

"git log"

结果显示,从最近到最远的显示日志,我们可以看到最近三次提交,最近的一次是“增加 333 内容”,上一次是“增加 222 内容”。

如果嫌上面显示的信息太多的话,可以用缩减版显示,如下:

"git log --pretty=oneline"

版本回退

现在我想使用版本回退操作,我想把当前的版本回退到上一个版本,要使用什么命令呢?可以使用如下2种命令,第一种是 git reset --hard HEAD^ ;那么如果要回退到上上个版本只需把 HEAD^ 改成 HEAD^^, 以此类推。那如果要回退到前 100 个版本的话,使用上面的方法肯定不方便,我们可以使用下面的简便命令操作:git reset --hard HEAD~100 即可。未回退之前的 readme.txt 内容如下:

"未回退内容"

回退到上一个版本,如下:

"回退到上一个版本"

查看现在 readme.txt 文件中的内容,如下:

"查看内容"

结果显示,”增加 333 内容”我们没有看到了。

恢复最新版本

现在我想恢复到最新的版本(有 333333 内容版本)要如何恢复呢?可以通过版本号回退。

但是现在的问题假如我已经关掉过一次 git bush,或者 333 内容的版本号我并不知道呢?要如何知道增加 3333 内容的版本号呢?如下:

"查看版本号"

结果显示,”增加 333 内容”的版本号是 c83a6bb。现在可以通过版本号回退了,如下:

"版本号回退"

结果显示,目前已经是最新的版本。

理解工作区、暂存区、版本库

工作区: 你在电脑上看到的目录,比如目录 testgit 里的文件(.git 隐藏目录版本库除外),以后需要再新建的目录文件等等都属于工作区范畴。

版本库: 工作区里的隐藏目录 .git,这个不属于工作区,这是版本库。版本库中存了很多东西:

  • 暂存区(stage) ——最重要!(暂存区是版本库的一部分)
  • Git为我们自动创建了第一个分支 master
  • 指向当前分支的指针 HEAD

前面说过使用 Git 提交文件到版本库有两步:

  • 第一步:git add 把文件添加进去,实际上就是把文件添加到暂存区;

  • 第二步:git commit 提交更改,实际上就是把暂存区的所有内容提交到当前分支上。

下面来举例说明。

在 readme.txt 再添加一行内容为 4444444,接着在目录下新建一个文件为 test.txt 内容为 test,我们先用命令git status 来查看下状态,如下:

"工作区、暂存区、版本库"

先使用 git add 命令把 2 个文件都添加到暂存区中,再使用 git status 来查看下状态,如下:

"git add"

接着使用 git commit 一次性提交到分支上,如下:

"一次性提交所有文件"

撤销修改、删除和恢复文件

命令 释义 备注
撤销修改
git checkout – file 丢弃 file 文件在工作区的修改(工作区-暂存区-版本库,回到上一阶段的修改)a.工作区修改后没有 add 到暂存区:回到和版本库一样的状态;b.工作区修改后 add 到暂存区后又有修改:回到添加暂存区后的状态 如果没有 –,则为创建分支命令
删除和恢复文件
rm file 删除工作区中的 file 文件 a.想要删除版本库中的 file 文件:直接 commit 掉;b.想要从版本库中删除 file 文件:git checkout – file
git checkout – file 丢弃 file 文件在工作区的修改(工作区 - 暂存区 - 版本库,回到上一阶段的修改)a.工作区修改后没有 add 到暂存区:回到和版本库一样的状态;b.工作区修改后 add 到暂存区后又有修改:回到添加暂存区后的状态 如果没有 –,则为创建分支命令

撤销修改

现在在 readme.txt 文件里面增加一行内容为 55555555,通过命令查看如下:

"修改555"

在未提交之前,我发现添加 55555555 内容有误,得马上恢复以前的版本,现在我可以有如下几种方法可以做修改:

  1. 如果知道要删掉哪些内容,直接手动更改去掉那些需要的文件,然后 add 添加到暂存区,最后 commit。

  2. 按以前的方法直接恢复到上一个版本。使用 git reset --hard HEAD^

但是现在我不想使用以上两种方法,想直接使用撤销命令该如何操作呢?首先在做撤销之前,我们可以先用 git status 查看下当前的状态,如下:

"git status"

可以发现,Git 会告诉你,git checkout -- file 可以将工作区做的修改全部撤销,如下:

  • "git checkout"

注意: git checkout -- readme.txt 中的 -- 很重要。如果没有 -- ,则命令变成创建分支了。

结果显示,内容 555 已结没有了。将工作区做的修改全部撤销有两种情况:

  1. 修改后还没有放到暂存区:撤销修改则回到和版本库一模一样的状态;
  2. 已经放入暂存区,接着又作了修改:撤销修改则回到添加暂存区后的状态。

对于第 2 种情况,继续做 demo,假如现在对 readme.txt 添加一行内容为 66666666,git add 增加到暂存区,如下:

"add 666"

接着添加内容 77777777,通过撤销命令让其回到暂存区后的状态。如下:

"撤销 777"

删除和恢复文件

假如现在版本库 testgit 目录添加一个文件 a.txt,然后提交。如下:

"添加 a.txt"

一般情况下,删除文件有两种方法:

  1. 直接在文件目录中删除文件 text.txt
  2. 使用命令 rm a.txt

如下:

"删除 a.txt、test.txt"

当前目录是这样的:

"当前目录"

如果想彻底从版本库中删掉了此文件的话,可以再执行 commit 命令提交掉。没有 commit 之前,想在版本库中恢复此文件如何操作呢?如下:

"提交 a.txt、test.txt"

再来看 testgit 目录,添加了 2 个文件,如下:

"当前目录"

创建、合并分支

理解 HEAD 和 master 指针

你已经知道,在版本回退里,每次提交,Git 都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在 Git 里,这个分支叫主分支,即 master 分支。严格来说,HEAD 并不是指向提交,而是指向 master,master 才是指向提交的,所以,HEAD 指向的就是当前分支。

结论:HEAD 指向当前分支,master 指向提交

理解分支管理策略

master 主分支:用来发布新版本,应该是非常稳定的。一般情况下不允许在上面干活。
一般情况下在新建的 dev 分支上干活,干完后,要发布,或者说 dev 分支代码稳定后可以合并到主分支 master 上来。

命令 释义 备注
创建、合并分支
git branch 查看分支 列出所有分支,当前分支前有星号
git branch xxx 创建分支 xxx
git checkout xxx 切换到分支 xxx
git checkout -b xxx 创建 + 切换分支 xxx 相当于git branch xxxgit checkout xxx
git merge xxx 在主分支上合并 xxx 分支 “Fast-forward“快进模式”:直接把 master 指向 xxx 的当前提交;删除分支后,丢掉分支信息 CONFLICT:产生冲突;删除分支后,保留分支信息”
git branch -d xxx 删除分支 xxx
解决冲突
git log –graph –pretty=oneline –abbrev-commit 带参数的 git log ,查看分支合并图 删除分支后,保留分支信息
“Fast forward” 模式 no-ff
git merge –no-ff -m “merge with no-ff” xxx 合并分支xxx,–no-ff:禁用Fast-forward“快进模式” 删除分支后,保留分支信息

创建、合并分支

首先,我们来创建并切换到 dev 分支上,然后查看当前分支,如下:

"创建并切换到 dev 分支"

git checkout -b xxx 表示创建 + 切换分支,相当于 git branch xxxgit checkout xxx

git branch 表示查看分支,列出所有分支,当前分支前有星号。

首先我们来查看下 readme.txt 内容,接着添加内容 77777777,再次查看内容并提交,如下:

"dev 支增加 777"

dev 分支工作已完成,现在切换到主分支 master 上,继续查看 readme.txt 内容,如下:

"切换到主分支"

我们发现内容 777 不见了,因为已经由 dev 分支切换到主分支了,主分支并没有增加 777 内容。现在我们把 dev 分支上的内容合并到分支 master 上,在 master 分支上,使用 git merge dev,继续查看内容。如下:

"合并分支"

我们发现多了一条 777,和 dev 分支最新的提交完全一样。

注意! merge 后显示的 Fast-forward 信息,表示这次合并是“快进模式”,即,直接把 master 指向 dev 的当前提交,合并速度非常快。

合并完成后,可以删除 dev 分支,如下:

"删除分支"

查看分支,发现只剩下主分支 master 了。

解决冲突

那么如何解决冲突呢?我们还是一步一步来,先新建一个新分支 fenzhi1,在 readme.txt 添加一行内容 8888888,然后提交,如下:

"fenzhi1 分支添加 888"

接着切换到 master 分支上,在最后一行添加内容 99999999,如下:

"主分支添加 999"

现在,在 master 分支上合并 fenzhi1,如下:

"主分支上合并 fenzhi1"

发现发生了冲突 CONFLICT,git bush 中显示分支的地方也变成了( master | MERGING)。查看状态和 readme.txt 内容,如下:

"查看状态和内容"

"查看状态和内容"

Git 用 <<<<<<<,=======,>>>>>>> 标记出不同分支的内容。

  • <<<HEAD :主分支修改的内容
  • >>>>>fenzhi1 :fenzhi1 上修改的内容

修改 readme.txt 内容后,保存并提交,如下:

"修改readme.txt内容"

"修改readme.txt内容"

发现显示分支的地方变回了(master)。如果想要查看分支合并的情况,需要使用命令 git log 命令,如下:

"git log"

git log 展示的信息量太大,一片文字看不过来,使用 git log --graph --pretty=oneline --abbrev-commit 命令可以显示分支合并图,如下:

"分支合并图"

“Fast forward”模式 no-ff

通常合并分支时,git 一般使用 “Fast forward” 模式,在这种模式下,删除分支后,会丢掉分支信息。

现在我们来使用带参数 –no-ff 来禁用 “Fast forward” 模式。来做 demo 演示下:

  1. 创建一个 dev 分支
  2. 修改 readme.txt 内容,增加 aaa
  3. 添加到暂存区
  4. 切换回主分支(master)
  5. 合并 dev 分支,使用命令 git merge -–no-ff -m “注释” dev
  6. 删除 dev 分支
  7. 查看分支
  8. 查看历史记录

如下:

"no-ff"

bug分支

命令 b释义
git stash 隐藏当前分支的工作现场
git stash list 查看 stash 隐藏的内容
git stash apply 恢复 stash 隐藏内容
git stash drop 删除 stash 内容
git stash pop 恢复并删除 stash 隐藏内容

在开发中,会经常碰到 bug 问题,那么有了 bug 就需要修复,在 Git 中,分支是很强大的,每个 bug 都可以通过一个临时分支来修复,修复完成后,合并分支,然后将临时的分支删除掉。

来做 demo 演示:新建 dev 分支,在 readme.txt 中增加 bbb。此时接到一个 404 bug,我们可以创建一个 404 分支来修复它,但是,当前的 dev 分支上的工作还没有提交。如下:

"遇到 404 bug"

并不是我不想提交,而是工作进行到一半时候,我们还无法提交,比如我这个分支 bug 要 2 天完成,但是我 issue - 404 bug 需要 5 个小时内完成。怎么办呢?还好,Git 还提供了一个 stash 功能,可以把当前工作现场 ”隐藏起来”,等以后恢复现场后继续工作。如下:

"stash 隐藏工作现场"

查看状态显示,nothing to commit, working directory clean,说明工作现场已被隐藏。现在可以通过创建issue-404 分支来修复 bug 了。

首先要确定在哪个分支上修复 bug。假设我现在要在主分支 master 上修复,那么要切换到主分支 master,然后创建一个临时分支 issue-404,如下:

"临时分支 issue-404"

修复 404 bug:将最后一行 aaa 改为 404 fixed,然后提交,如下:

"修复 404bug"

修复完成,切换到 master 分支上,并完成合并,最后删除 issue-404 分支。如下:

"完成合并,删除 issue-404分支"

现在,可以回到 dev 分支上干活了。

"回到 dev 分支"

查看状态表明,现在的工作区是干净的。那么我们工作现场去哪里呢?我们可以使用命令 git stash list来查看下。如下:

"git stash list"

工作现场还在,Git 把 stash 内容存在某个地方了,但是需要恢复一下,可以使用如下2个方法:

  1. git stash apply 恢复。恢复后,stash 内容并不删除,你需要使用命令 git stash drop 来删除
  2. 使用 git stash pop。恢复的同时把 stash 内容也删除了

如下:

"恢复工作区"

这样就恢复了之前的工作区,可以继续 dev 分支的工作了。

Github远程仓库

先注册 GitHub 账号,由于你的本地 Git 仓库和 GitHub 仓库之间的传输是通过 SSH 加密的,所以需要设置 SSH Key。

创建 SSH Key

查看是否已经有 SSH 密钥:
打开用户主目录 “C:\Users\Administrator.hp-PC” ,
看看有没有 .ssh 目录。

  • 如果有,再看看这个目录下有没有 id_rsa 和 id_rsa.pub 这两个文件。如果有,可以直接跳至下一小节
  • 如果已经有 SSH 密钥,想要重新生成 SSH 密钥,需要清理原有 SSH 密钥:
  • 1
    2
    3
    $ mkdir key_backup
    $ cp id_rsa* key_backup
    $ rm id_rsa*
  • 如果没有,打开命令行,输入命令 ssh-keygen -t rsa –C “youremail@example.com”。此处的邮箱地址,你可以输入自己的邮箱地址。在回车中会提示你输入一个密码,这个密码会在你提交项目时使用,如果为空的话提交项目时则不用输入。这个设置是防止别人往你的项目里提交内容。

由于我本地此前运行过一次,所以本地有,如下所示:

".ssh"

id_rsa 是私钥,不能泄露出去,id_rsa.pub 是公钥,可以放心地告诉任何人。由于之前使用 Github 客户端,因此还有github_rsa 和 github_rsa.pub 两个文件。known_hosts 文件如果没有暂时不管。

验证是否连接成功,连接成功显示 Hi baoyuzhang! You've successfully authenticated, but GitHub does not provide shell access.。如下:

"验证是否连接成功"

Github中添加SSH Key

登录 GitHub,点击个人头像打开 “settings”,再打开 “SSH and GPG keys” 页面,然后点击 “New SSH Key” ,填上任意 title,在 “Key” 文本框里黏贴 id_rsa.pub 文件的内容,点击 Add Key,你就应该可以看到已经添加的 key。如下:

"Github 中添加 SSH Key"

添加远程库

先创建本地 Git 仓库,再创建 GitHub 仓库,两个仓库同步

现在的情景是:我们已经在本地创建了一个 Git 仓库后,又想在 GitHub 创建一个 Git 仓库,并且希望这两个仓库进行远程同步,这样 GitHub 的仓库可以作为备份,又可以其他人通过该仓库来协作。

首先,登录 GitHub 上,然后在右上角点击 “+” 找到 “New repository” 创建一个新的仓库。如下:

"create a new repo"

"create a new repo"

在 Repository name 填入 testgit,其他保持默认设置,点击 “Create repository” 按钮,就成功地创建了一个新的Git 仓库:

"new repo"

目前,在 GitHub 上的这个 testgit 仓库还是空的。现在把已有的本地仓库 testgit 与之关联,然后,把本地仓库的内容推送到 GitHub 仓库。

"推送到 GitHub 仓库"

把本地库的内容推送到远程,使用 git push 命令,实际上是把当前分支 master 推送到远程。

由于远程库是空的,我们第一次推送 master 分支时,加上了 –u 参数,Git 不但会把本地的 master 分支内容推送的远程新的 master 分支,还会把本地的 master 分支和远程的 master 分支关联起来,在以后的推送或者拉取时就可以简化命令。推送成功后,可以立刻在 GitHub 页面中看到远程库的内容已经和本地一模一样了:

"一模一样"

从现在起,只要本地作了提交,通过命令 git push origin master 就可以把本地 master 分支的最新修改推送到 GitHub 上了,现在你就拥有了真正的分布式版本库了。

先创建 GitHub 仓库,再从 GitHub 仓库克隆

上面我们了解了先有本地库,后有远程库时候,如何关联远程库。现在我们想,假如远程库有新的内容了,我想克隆到本地来 如何克隆呢?

首先,登录 GitHub ,创建一个新的仓库,名字叫 testgit2 如下:

"create a new repo"

"create a new repo"

"create a new repo"

现在,远程库已经准备好了,下一步是使用命令 git clone 克隆一个本地库了。如下:

"克隆一个本地库"

在本地目录就生成了 testgit2 目录,如下:

"克隆一个本地库"


本文作者:baoyuzhang
原文地址:https://baoyuzhang.github.io/
声明:如需转载,请联系原作者


欢迎大家在评论区留下你的想法和感受!

欢迎大家关注知乎专栏:全栈成长之路

也欢迎大家加入学习交流QQ群:637481811

LeviDing wechat
欢迎扫描上方微信公众号,订阅博客获得实时动态!
坚持原创技术分享,您的支持将支持我更好的创作!
0%