程序员Git

Git 学习 ---Git Pro精简版

2018-06-20  本文已影响49人  琅筑

Git 学习 ---《Git Pro》精简版

写在前面

最近准备着手做一个项目的时候,突然发现自己之前使用Git和github的时候,只会简单的使用 git add . |git commit -m "..." | git push 命令。觉得自己对于git的使用和掌握,在自己玩一玩的情况下还可以,但是生产环境这点只是实在不够,于是准备从头开始学习git,望众大佬指教。

本文主要参考Git官方的书籍 ——《Git Pro》,以及Git在YouTube的官方视频教程,参考内容会在本文最后的参考链接中给出,感谢互联网这个开源的世界,感谢众多在互联网人辛苦的耕耘。本人会写尽量多的例子,自己学习的同时也希望读了这篇文章的人有所收获。技术在更新,与诸君共勉!

1.起步

1.1 关于版本控制

版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 在本书所展示的例子中,我们对保存着软件源代码的文件作版本控制,但实际上,你可以对任何类型的文件进行版本控制。

本地版本控制

为了解决人们对版本控制的需要,同时避免每一个版本都复制一份加上时间戳这种方法的混淆,以及容易出现错误的问题。人们很久之前就开始使用本地版本控制,大多是采用某种简单的数据库来记录文件的历次更新。其中最流行的是RCS,现在许多计算机上面还都存在它的影子,比如Mac OS X上面的rcs命令。

集中式版本控制

出于对"如何让在不同系统上的开发者协同工作?"这个问题的思考。于是,集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS)应运而生。 这类系统,诸如 CVS、Subversion 以及 Perforce 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。 多年以来,这已成为版本控制系统的标准做法。

优点是:终于可以让以前单台机器上的版本控制变成了可以多人协同的版本控制。

缺点是:中央服务器的单点故障,会导致协同工作的终止,所有人都无法提交更新。 如果中心数据库所在的磁盘发生损坏,又没有做恰当备份,毫无疑问你将丢失所有数据。

分布式版本控制

由于集中式版本控制带来的问题,于是分布式版本控制系统(Distributed Version Control System,简称 DVCS)面世了 。在这类系统中,像 Git、Mercurial、Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。

在这类系统中,像 Git、Mercurial、Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。

1.2 Git 简史

自诞生于 2005 年以来,Git 日臻成熟完善,在高度易用的同时,仍然保留着初期设定的目标。 它的速度飞快,极其适合管理大项目,有着令人难以置信的非线性分支管理系统。

1.3 Git基础

Git 和其它版本控制系统(包括 Subversion 和近似工具)的主要差别在于 Git 对待数据的方法。 概念上来区分,其它大部分系统以文件变更列表的方式存储信息。 这类系统(CVS、Subversion、Perforce、Bazaar 等等)他们所保存的信息是一个文件与之前的文件的变化量。

直接记录快照而非差异性比较

与此不同Git使用的是快照流的方式。每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个 快照流

几乎所有操作都是本地的

由于本地磁盘就有完整的项目历史,因此绝大多数的操作无需连接网络。与其他系统相比,会让你有完全不同的飞一样的体验。

Git保证数据的完整性

Git 中所有数据在存储前都计算校验和,然后以校验和来引用。 这意味着不可能在 Git 不知情时更改任何文件内容或目录内容。 这个功能建构在 Git 底层,是构成 Git 哲学不可或缺的部分。 若你在传送过程中丢失信息或损坏文件,Git 就能发现。Git 用以计算校验和的机制叫做 SHA-1 散列(hash,哈希)。

Git一般只添加数据

同别的 VCS 一样,未提交更新时有可能丢失或弄乱修改的内容;但是一旦你提交快照到 Git 中,就难以再丢失数据,特别是如果你定期的推送数据库到其它仓库的话

三种状态

由此引入 Git 项目的三个工作区域的概念:Git 仓库、工作目录以及暂存区域。

git工作区.png

Git 仓库目录是 Git 用来保存项目的元数据和对象数据库的地方。 这是 Git 中最重要的部分,从其它计算机克隆仓库时,拷贝的就是这里的数据。

工作目录是对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。

暂存区域是一个文件,保存了下次将提交的文件列表信息,一般在 Git 仓库目录中。 有时候也被称作`‘索引’',不过一般说法还是叫暂存区域。

基本的 Git 工作流程如下:

  1. 在工作目录中修改文件。

  2. 暂存文件,将文件的快照放入暂存区域。

  3. 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。

1.4 命令行

Git 有多种使用方式。 你可以使用原生的命令行模式,也可以使用 GUI 模式。作为一个coder,很明显还是觉得命令行更加实用,快速,炫酷。当然GUI也有集成了很多功能

1.5 安装Git

自行goole or baidu 关键词 "git 安装"

1.6 初次运行之前的配置

配置用户名和密码:

git config --global user.name

git config --global user.email

如果上面的不对请尝试:

git config --global --replace-all user.name ""

git config --global --replace-all user.email "****"

查看配置信息:

git config --list

结果如下:

core.symlinks=false
core.autocrlf=true
core.fscache=true
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
help.format=html
rebase.autosquash=true
http.sslcainfo=C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
http.sslbackend=openssl
diff.astextplain.textconv=astextplain
filter.lfs.clean=git-lfs clean -- %f
filter.lfs.smudge=git-lfs smudge -- %f
filter.lfs.process=git-lfs filter-process
filter.lfs.required=true
credential.helper=manager
user.email=(刚才设置的email)
user.name=(刚才设置的name)
core.autocrlf=true(开启自动识别换号)
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
remote.origin.url=https://github.com/fungi8/(项目名称)
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*

Git配置的优先级

1.7 获取帮助

git help <verb>

git <verb> --help

man git -<verb>

2. Git基础

2.1 获取Git仓库

有两种取得 Git 项目仓库的方法。 第一种是在现有项目或目录下导入所有文件到 Git 中; 第二种是从一个服务器克隆一个现有的 Git 仓库。

在现有目录中初始化仓库

git init

该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。

克隆现有的仓库

如果你想获得一份已经存在了的 Git 仓库的拷贝,比如说,你想为某个开源项目贡献自己的一份力,这时就要用到 git clone 命令。

Git 克隆的是该 Git 仓库服务器上的几乎所有数据,而不是仅仅复制完成你的工作所需要文件。

比如:

git clone https://github.com/libgit2/libgit2

这会在当前目录下创建一个名为 “libgit2” 的目录,并在这个目录下初始化一个 .git 文件夹,从远程仓库拉取下所有数据放入 .git 文件夹,然后从中读取最新版本的文件的拷贝。

git clone https://github.com/libgit2/libgit2 mylibgit

执行与上一个命令相同的操作,不过在本地创建的仓库名字变为 mylibgit

Git 支持多种数据传输协议,包括HTTPS SSH。

2.2 记录每次更新到仓库
文件生命周期.png

可以使用 git status 来查看那些文件处于什么状态。

如果新建一个文件,这个文件就会是Untracked files 状态。这表明git之前的快照中没有这个文件,并且Git也不会把它纳入到自动跟踪的范围。

跟踪新文件

使用命令 git add 开始跟踪一个文件 ,使用这个命令之后Git的状态变为了 Changes to be committed ,说明文件已经进入已暂存状态。

暂存已修改文件

如果使用 git stauts 命令查看Git状态看到的是Changes not staged for commit 表明这个文件是已经被修改的,但是还没有放入暂存区。要暂存这次更新需要使用 git add 将修改的文件,再次加入到暂存区中。

状态简览

git status 命令出现的信息很繁琐,可以使用 git status -s 得到一种更加紧凑的输出。

新添加的未跟踪文件前面有 ?? 标记,新添加到暂存区中的文件前面有 A 标记,修改过的文件前面有 M 标记。

M 有两个可以出现的位置,出现在右边的 M 表示该文件被修改了但是还没放入暂存区,出现在靠左边的 M 表示该文件被修改了并放入了暂存区。

忽略文件

一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。

在这种情况下,我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件模式。

查看已暂存和未暂存的修改

通常会迷茫两个问题:当前做的哪些更新还没有暂存? 有哪些更新已经暂存起来准备好了下次提交?尽管可以使用 git status 来查看但是有时候会显得很模糊,而 git diff 通过文件补丁的形式显示具体那些地方发什么那些变化。此命令比较的是工作目录中当前文件和暂存区域快照之间的差异, 也就是修改之后还没有暂存起来的变化内容。

若要查看已暂存的将要添加到下次提交里的内容,可以用 git diff --cached 命令。(Git 1.6.1 及更高版本还允许使用 git diff --staged,效果是相同的,但更好记些。)

还有两个很好用的命令,一个是 git diff --color-words 这个命令会告诉你修改了哪些词。另外一个是 git diff --word-diff 同样也会告诉你修改的词是什么。

提交更新

每次准备提交前,先用 git status 看下,是不是都已暂存起来了, 然后再运行提交命令 git commit

这种方式会启动文本编辑器以便输入本次提交的说明。 可以使用 git config --global core.editor 命令设定你喜欢的编辑软件

也可以使用 git commit -m "" 直接在双引号中记录下你对本次提交的说明。

跳过使用暂存区域

有时候使用 git add 会显得很精致,但是同时也会很繁琐。因此可以使用 git commit -a 来跳过暂存区域,这个时候Git会直接把所有跟踪过得文件暂存起=起来一并提交。

移除文件

可以用 git rm 命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了 。如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f 这是一种安全特性,用于防止误删还没有添加到快照的数据,这样的数据不能被 Git 恢复。

另外一种情况是,我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。 换句话说,你想让文件保留在磁盘,但是并不想让 Git 继续跟踪。 可以使用 git rm --cached README

移动文件

如果需要对Git仓库中某一个文件进行改名的话可以使用 git mv file_from file_to 如果你熟悉Linux应该不陌生。

2.3 查看历史提交

在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的工具是 git log 命令。

默认不用任何参数的话,git log 会按提交时间列出所有的更新,最近的更新排在最上面。 正如你所看到的,这个命令会列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明。

-p,用来显示每次提交的内容差异。 你也可以加上 -2 来仅显示最近两次提交 。

git log --oneline 这个命令可以更加简明的看到每次提交的信息,和提交信息的唯一表示符。

如果你想看到每次提交的简略的统计信息,你可以使用 --stat选项 --stat 选项在每次提交的下面列出所有被修改过的文件、有多少文件被修改了以及被修改过的文件的哪些行被移除或是添加了。 在每次提交的最后还有一个总结。

另外一个常用的选项是 --pretty。 这个选项可以指定使用不同于默认格式的方式展示提交历史。 这个选项有一些内建的子选项供你使用。 比如用 oneline 将每个提交放在一行显示,查看的提交数很大时非常有用。 另外还有 shortfullfuller 可以用,展示的信息或多或少有些不同,请自己动手实践一下看看效果如何。

还有按照时间作限制的选项,比如 --since--until 也很有用。 例如,下面的命令列出所有最近两周内的提交

2.4 撤销操作

有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend选项的提交命令尝试重新提交 git commit --amend

取消暂存的文件

git reset

2.5 远程仓库的使用

查看远程仓库

如果想查看你已经配置的远程仓库服务器,可以运行 git remote 命令。 它会列出你指定的每一个远程服务器的简写 。 如果你已经克隆了自己的仓库,那么至少应该能看到 origin - 这是 Git 给你克隆的仓库服务器的默认名字 。你也可以指定选项 -v,会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL。

添加远程仓库

git remote add <shortname> <url> 添加一个新的远程 Git 仓库,同时指定一个你可以轻松引用的简写:

git remote add JonWong https://github.com/fungi8/.....

从远程仓库中抓取与拉取

git fetch [remote-name] 这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。

如果你使用 clone 命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 “origin” 为简写。 所以,git fetch origin 会抓取克隆(或上一次抓取)后新推送的所有工作 。必须注意 git fetch 命令会将数据拉取到你的本地仓库 - 它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。 当学习了git分支之后,你就可以使用 git pull命令来自动的抓取然后合并远程分支到当前分支。

推送到远程仓库

当你想分享你的项目时,必须将其推送到上游。 这个命令很简单:git push [remote-name] [branch-name]。 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先将他们的工作拉取下来并将其合并进你的工作后才能推送。

查看远程仓库

如果想要查看某一个远程仓库的更多信息,可以使用 git remote show [remote-name] 命令。 此时[remote-name] 可以使用别名。例如:git remote show origin

远程仓库的移除与重命名

如果想要重命名引用的名字可以运行 git remote rename 去修改一个远程仓库的简写名。

如果因为一些原因想要移除一个远程仓库 - 你已经从服务器上搬走了或不再想使用某一个特定的镜像了,又或者某一个贡献者不再贡献了 - 可以使用 git remote rm

2.6 打标签

列出标签

git tag

创建标签

Git 使用两种主要类型的标签:轻量标签(lightweight)与附注标签(annotated)。一个轻量标签很像一个不会改变的分支 - 它只是一个特定提交的引用。附注标签是存储在 Git 数据库中的一个完整对象。 它们是可以被校验的;其中包含打标签者的名字、电子邮件地址、日期时间;还有一个标签信息;并且可以使用 GNU Privacy Guard (GPG)签名与验证。

附注标签

在 Git 中创建一个附注标签使用命令:git tag -a -m 选项指定了一条将会存储在标签中的信息,类似于commit

2.7 Git别名

Git 并不会在你输入部分命令时自动推断出你想要的命令。 如果不想每次都输入完整的 Git 命令,可以通过 git config 文件来轻松地为每一个命令设置一个别名。

3. Git分支

几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。 Git 处理分支的方式可谓是难以置信的轻量,创建新分支这一操作几乎能在瞬间完成,并且在不同分支之间的切换操作也是一样便捷 。

3.1 分支简洁
3.2 分支的新建与合并
3.3 分支管理
3.4 分支开发工作流
3.5 远程分支
3.6 变基
3.7 总结

基本上面的知识就够日常的使用了,下面相当于扩展部分,但是内容都在Pro Git中出现


4.服务器上的Git

4.1 协议
4.2 在服务器上搭建Git
4.3 生成SSH公钥
4.4配置服务器
4.5 Git守护进程
4.6 Smart HTTP
4.7 GitWeb
4.8 GitLab
4.9 第三方托管的选择
4.10 总结

5. 分布式Git

5.1 分布式工作流程
5.2向一个项目贡献
5.3 维护项目
5.4总结

6. GitHub

6.1 账户的创建和配置
6.2 对项目做出贡献
6.3 维护项目
6.4 管理组织
6.5 脚本GitHub
6.6 总结

7. Git工具

7.1 选择修改版本
7.2 交互式暂存
7.3储藏与清理
7.4 部署工作
7.5搜索
7.6 重写历史
7.7 重置揭秘
7.8 高级合并
7.9 Rerere
7.10 使用Git调试
7.11 子模块
7.12 打包
7.13 代替
7.14 凭证存储
7.15 总结

8. 自定义Git

8.1 配置Git
8.2 Git属性
8.3 Git钩子
8.4 使用强制策略的一个例子
8.5总结

9. Git与其他系统

9.1 作为客户端的Git
9.2 迁移到Git
9.3 总结

10. Git内部原理

10.1 底层命令和高层命令
10.2 Git对象
10.3 Git引用
10.4 包文件
10.5 引用规则
10.6 传输协议
10.7 维护与数据恢复
10.8 环境变量
10.9 总结

参考链接:

Pro Git

Github官方教程,nowcoder获权翻译版本

上一篇下一篇

猜你喜欢

热点阅读