git学习笔记

起步

关于版本控制系统

什么是版本控制系统?版本控制系统是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。作为程序员,平时通常都是对源代码进行版本控制,但是实际上,我们可以对任何类型的文件进行版本控制。

本地版本控制系统

最早的版本的控制系统为本地版本控制系统,其工作原理通常是在硬盘上保存补丁集,通过应用所有补丁,可以重新计算出各个版本的文件内容。但本地版本控制系统无法让不同系统上开发者协同工作。

集中化的版本控制系统

为了解决“如何让不同系统上的开发者协同工作”这一问题,集中化的版本控制系统(Centraiized Version Control System, 简称CVCS)应运而生。这类系统,比如SVN,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或提交更新。
这种做法有一下优点:

  • 不同系统上的开发者可以协作工作,每个人都能在一定程度上看到项目中其他人在做什么
  • 管理员可以轻松控制每个开发者的权限
  • 管理一个服务端的CVCS要远比在每个客户端上维护其本地数据库来的轻松容易

当然凡事均有两面性,CVCS仍有一些缺点:

  • 如果中央服务器,那么团队协作者将无法更新或者提交,将无法协同工作。
  • 如果中心数据库损毁,那么你将丢失所有数据–包括每个项目的变更历史。

分布式版本控制系统

在分布式版本控制系统(Distributed Version Control System)中,比如Git, 客户端并不仅是提取最新版本的文件快照,而是把代码仓库完整地镜像下来,这样一来,即使服务器发生故障,它也可以用任何一个本地仓库进行恢复。

Git基础

注意,接下来的内容非常重要,若你了解了Git的思想和基本工作原理,用起来就会知其所以然,游刃有余。

直接记录快照,而非差异对比

Git和其他版本控制系统的主要差别在于Git对待数据的方式,此处以Git和SVN作对比。
SVN以文件变更列表的形式存储信息,它们的存储信息可以看作是一组基本文件和各个文件随时间逐步累积的差异,如下图:
在这里插入图片描述
但Git不以以上方式保存数据,Git更像是把数据看作是对小型文件系统的一组快照,每次你提交更新时,Git会对修改的文件制作一个快照并保存这个快照的索引,Git对待数据更像是一个快照流,如下图:
在这里插入图片描述
我们在学习Git分支管理的时候,将探究这种方式对待数据所能获得的益处。

近乎所有操作都是本地执行

由于你在本地磁盘上有了项目的完整镜像,所以大部分操作都是本地操作,而且都可以瞬间完成。
比如,你要浏览项目的历史,Git不需要去外连服务器去获取历史,它只需直接从本地数据库中读取。即使你处于脱机状态下,你也可以愉快的提交(commit),然后等到有网路连接时再上传(push)。而上面两个例子,在使用SVN时均无法做到。

Git保证完整性

Git中所有数据在存储前都计算校验和,然后以校验和引用。Git用以计算校验和的机制叫做SHA-1散列(哈希),这是一个由40个十六进制字符组成的字符串,基于Git中文件的内容或目录结构计算出来的,如下:

24b9da6552252987aa493b52f8696cd6d3b00373

Git的使用过程中会进场看到这种哈希值。实际上,Git数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名。

Git一般只添加数据

你执行的Git的操作,几乎只往Git数据库中添加数据,很难让Git执行任何不可逆操作,所以一旦你提交快照到Git中,就难以再丢失数据。

三种状态

Git有三种状态,你的文件可能处于其中之一:已提交(commited)、已修改(modified),已暂存(staged)。
已提交表示数据已经安全的保存到本地数据库中。
已修改表示修改了文件,但还没保存到数据库中。
已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
由此引入了Git项目的三个工作区域的概念:Git仓库,工作目录及暂存区域。
Git基本工作流程如下图所示:
在这里插入图片描述

  1. 在工作目录中修改文件,修改过的文件处于已修改状态。
  2. 暂存文件(git add), 将文件快照存入暂存区域,此时文件处于暂存状态
  3. 提交更新(git commit),找到暂存区域的文件,将快照存储到Git仓库目录,此时文件处于已提交状态。

命令行

Git有多种使用方式,你可以使用原始的命令行模式,也可以使用GUI模式。
学习Git的时候建议使用命令行模式,有以下几点原因:

  • 只有在命令行模式中你才能执行Git的所有命令,而大多数GUI软件只实现了Git所有功能的一个子集以降低操作难度。
  • 有些GUI软件可能会受平台限制,但是所有平台都有命令行工具
  • 不同的人常常会安装不同的GUI软件,但所有人一定会有功能类似的命令行终端。

安装Git

在你使用Git前,需要将它安装在你的计算机上,即使已经安装,最好将其升级至最新版本。
各安装方式如下:

  1. Linux:http://git-scm.com/download/linux
  2. Mac:http://git-scm.com/download/mac
  3. Windows:http://git-scm.com/download/win
  4. 源代码安装:https://github.com/git/git/releases

初次运行Git前的配置

Git自带一个git config的工具来帮助控制Git外观和行为的配置变量,这些变量存储在三个不同的位置:

  1. /etc/gitconfig文件:包含系统上每一个用户及他们仓库的通用配置,使用命令行git config --system 读取此配置。
  2. ~/.gitconfig 或 ~/.config/git/config 文件:只针对当前用户。 使用命令行git config --global 读取此配置。
  3. .git/config文件:当前使用仓库目录的配置文件,只针对此仓库。

以上3种配置,每一个级别的配置覆盖上一个级别的配置。

用户信息

当安装完git应该做的第一件事就是设置你的用户名称和邮件地址(注意,并不是你的git账号密码),这样做很重要,因为每一个Git的提交都会使用这些信息。命令行设置如下:

git config --global user.name "zhang3"
git config --global user.email zhang3@example.com

很多GUI工具均会在第一次运行时帮助你配置这些信息。

文本编辑器

你可以配置默认的文本编辑器,当Git需要你输入信息时会调用它,如果未配置,Git会使用操作系统默认的文本编辑器。

git config --global core.editor notepad2

检查配置信息

如果你想检查你的配置,可以通过git config --list命令来列出所有Git当时能找到的配置。你可以通过输入 git config 来检查 Git 的某一项配置

git config --list
git config user.name

获取帮助

有三种方法可以找到Git命令的使用方法:

git help <verb>
git <verb> --help
man git-<verb>

比如要想获得config命令的手册

git help config

这些命令很棒,因为你随时随地可以使用而无需联网。
如果你觉得手册不够用,你可以尝试在FreeNode IRC服务器的#git和#github频道来寻求帮助。

Git基础使用方法

获取Git仓库

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

从现有目录中初始化仓库

如果你打算使用Git对一个现有的项目进行管理,你只需要进入该项目目录并输入:

git init

该项目将创建一个名为.git的子目录,这个子目录含有初始化的Git仓库中所有的必须文件,这些文件是Git仓库的骨干。但是,这个时候,你的项目中的文件还没有被追踪。你可以通过git add命令来实现对文件的追踪,然后执行git commit提交:

//添加文件夹下所有以".c"结尾的文件
git add *.c
//提交并附加上版本日志
git commit -m "initial project version"

稍后我们再逐一解释每一条指令的意思。

克隆现有仓库

如果你想获得一份已经存在的Git仓库的拷贝,可以使用git clone命令。请你留心一下此处使用的命令是"clone"而不是"checkout",这是因为Git克隆的是该仓库中的几乎全部数据,而不是仅仅复制完成你的工作所需文件。
命令格式如下:

git clone [url]

比如:

//Clone with http
git clone http://gitlab.kaiqitech.com/k7game/monitor/grafana-dashboards.git
//Clone with SSH
git clone git@gitlab.kaiqitech.com:k7game/monitor/grafana-dashboards.git

如果你想在克隆远程仓库的时候,自定义本地仓库名,那么你可以使用如下命令:

git clone [url] [name]

比如:

git clone http://gitlab.kaiqitech.com/k7game/monitor/grafana-dashboards.git myDashboards

记录每次更新到仓库

工作目录下的每一个文件都不外乎两种状态:已追踪或未追踪。已追踪的文件是指那些被纳入版本控制的文件,除此之外的其他文件都属于未追踪文件。使用Git时的文件声明周期如下:
在这里插入图片描述

检查当前仓库状态

要查看哪些文件处于什么状态,可以用git status命令,如下:
在这里插入图片描述
git status 命令的输出十分详细,但其用语较为繁琐,如果你想要一种更为紧凑的格式输出,可以在git status中加入-s或者–short,如下:

git status -s
git status --short

在这里插入图片描述

跟踪新文件

使用命令git add 开始跟踪一个文件。git add 命令使用文件或目录的路径作为参数;如果参数是目录的路径,该命令将递归地跟踪该目录下地所有文件。

//追踪test.txt文件
git add test.txt
//追踪test文件夹下地所有文件
git add C:test\

暂存已修改文件

如果我们修改了一个已被跟踪地文件,该文件会出现在“changes not staged for commit”列表中,说明该已跟踪文件内容发生了变化,但还没有放入缓存区。要暂存这次更新,需要git add命令。
git add 是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。这个命令应该理解为“添加内容到下一次提交中”更为合适。

忽略文件

一般我们总会有些文件无需纳入Git的管理,也不希望它们总是出现在未跟踪文件列表中。这种情况下,我们可以创建一个名为.gitignore的文件,列出要忽略的文件模式。
文件 .gitignore 的格式规范如下:

  • 所有空行或者以#开头的行都会被Git忽略
  • 可以使用标准的glob模式匹配
  • 匹配模式可以以(/)开头防止递归
  • 匹配模式可以以(/)结尾指定目录
  • 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。

所谓的glob模式是指shell所使用的简化了的正则表达式。星号(*)匹配零个或多个任意字符;[abc]匹配任何一个列在方括号内的字符;问号(?)只匹配任意一个字符;如果在方括号内使用短划线分隔两个字符,表示所有在这两个字符范围内的字符均可匹配(如[0-9]表示匹配0到9的数字)。使用两个星号表示匹配任意中间目录(比如’a/**/'可以匹配a/z, a/b/z, a/b/c/z)。
我们来看一个.gitignore的例子,如下:

# 忽略所有.a后缀文件
*.a
# 但是追踪lib.a文件
!lib.a
# only ignore the TODO file in the current directory, not subdir/TODO
/TODO
# 忽略目录build下的所有文件
build/
# 忽略doc目录下的txt文件,但不忽略其子目录的txt文件
doc/*.txt
# 忽略doc目录及其子目录的所有pdf文件
doc/**/*.pdf

GitHub 有一个十分详细的针对数十种项目及语言的 .gitignore 文件列表,你可以在https://github.com/github/gitignore 找到它。

查看已暂存以及未暂存的修改

如果git status命令的输出对你太过模糊,你想知道具体修改了什么地方,你可以使用git diff命令来查看。
要查看尚未暂存的文件更新了哪些部分,不加参数直接输入 git diff即可。
在这里插入图片描述
请注意,git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 所以有时候你一下子暂存了所有更新过的文件后,运行 git diff 后却什么也没有,就是这个原因。
若要查看已暂存的将要添加到下次提交的内容,可以使用git diff --cached命令。
在这里插入图片描述

提交更新

使用git commit命令可以把暂存区域保存的数据进行提交,这种方式会启动文本编辑器以便输入本次提交的说明(文本编辑器通过git config --global core.editor来设定),如下:
在这里插入图片描述
另外你也可以在commit命令后添加-m选项,将提交信息与命令放在同一行,如下:
在这里插入图片描述

跳过使用暂存区域

尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁琐。Git提供了一个跳过使用暂存区域的方式,只要在提交的时候给git commit加上-a选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤。

git commit -a

移除文件

要从Git中移除某个文件,必须先把此文件从已追踪列表中移除,然后提交。
可以使用git rm命令来完成此项工作,并连带着从工作目录中删除此文件,这样以后此文件就不会出现在未跟踪列表中。

git rm filename

如果删除之前已经改过并且已暂存的文件,则必须要用强制删除选项 -f(Force的首字母),这是一种安全特性,防止误删还没有提交的数据,如下:
在这里插入图片描述
git rm 命令也可以使用 glob 模式删除相匹配的文件,如:

#删除log文件夹下的所有log后缀文件
git rm log/\*.log

移动文件

要在 Git 中对文件改名,可以这么做:

git mv file_from file_to

其实 git mv命令相当于运行了下面三天命令:

mv file_from file_to
git rm file_from
git add file_to

查看提交历史

使用命令行git log可以查看一个项目的提交历史。
默认不用任何参数的话,git log 会按提交时间列出所有的更新,更新信息会列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明,如下图:
在这里插入图片描述
git log 有许多选项可以帮助你搜索你要的提交,常见的罗列如下:

  • git log -p:用来显示提交的内容差异
  • git log --stat:显示每次提交的简略信息
  • git log --oneline:将每个提交放在一行显示
  • git log -:n为任意整数,表示仅显示最近的若干条提交

git log 还有许多其他附加选项,在此不一一列举,可以自行查询git官方文档。

撤销操作

弥补提交

有时我们提交完了才发现漏了几个文件没有提交,或者提交信息写错了,那么我们可以使用–amend选项的提交命令尝试重新提交:

git commit --amend

例如你可以像下面一样操作:

git commit -m "init commit"
git add forgotten_file
git commit --amend

注意最后你只会有一个提交,第二次提交将替代第一次提交的结果。

取消暂存的文件

如果我们已经修改并暂存了某个文件,但突然由于某些缘故想要取消暂存此文件,可以通过git reset命令来操作,如下:

git reset HEAD <file>

撤销对文件的修改

如果你不想保留对某个文件的修改,你可以通过git checkout 命令来将其还原为上次提交时的版本:

git checkout --<file>

远程仓库的使用

为了能在任意git项目上协作,你需要知道如何管理自己的远程仓库。远程仓库是指托管在英特网或者其他网络中的你的项目版本库。

查看远程仓库

如果想查看你已经配置的远程仓库服务器,可以运行git remote命令。
在这里插入图片描述
origin是Git给你克隆的仓库服务器的默认名字。
添加-v会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL,如下图:
在这里插入图片描述

添加远程仓库

可以使用git remote add 来添加新的远程git仓库,如下:

git remote add <shortname> <url>

shortname为你为这个仓库指定的简写名,如下:

git remote add pb http://github.com/paulboone/ticgit

现在你可以在命令行中使用字符串pb来代替整个URL,比如你想拉取仓库中的最新信息,可以如下:

git fetch http://github.com/paulboone/ticgit
git fetch pb

从远程仓库中抓取与拉取

可以使用以下两个命令从远程仓库获取数据

git fetch [remote-name]
git pull [remote-name]

remote-name为远程仓库名,一般默认为“origin”,也可以在clone仓库的时候为其指定简写名。

推送到远程仓库

当你想分享你的项目时,必须将其推送到上游, 这个命令很简单,如下:

git push [remote-name] [branchname]

例如:

git push origin master

只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先将他们的工作拉取下来并将其合并进你的工作后才能推送。

查看远程仓库

如果想要查看某一个远程仓库的更多信息,可以使用 git remote show 命令:

git remote show [remote-name]

在这里插入图片描述

远程仓库的移除与重命名

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

git  remote rename [oldname] [newname]

值得注意的是这同样也会修改你的远程分支名字。
如果因为一些原因想要移除一个远程仓库,可以使用 git remote rm来完成,比如:

//移除origin远程仓库
git remote rm origin

打标签

像其他版本控制系统(VCS)一样,Git 可以给历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点(v1.0 等等)。

列出标签

在 Git 中列出已有的标签是非常简单直观的。 只需要输入 git tag:
在这里插入图片描述
你也可以使用特定的模式查找标签, 比如下图,只查看0.99版本相关的标签:
在这里插入图片描述

创建标签

Git 使用两种主要类型的标签:轻量标签与附注标签。通常建议创建附注标签,因为附注标签包含了更多的信息,比如打标签者的名字、电子邮件地址、日期时间等。

附注标签

在 Git 中创建一个附注标签是很简单的。 最简单的方式是当你在运行 tag 命令时指定 -a 选项:

git tag -a v1.4 -m 'my version 1.4'

-m 选项指定了一条将会存储在标签中的信息,通过使用 git show 命令可以看到标签信息与对应的提交信息:
在这里插入图片描述

轻量标签

创建轻量标签,不需要使用 -a、-s 或 -m 选项,只需要提供标签名字:

git tag v1.0

后期打标签

你也可以对过去的提交打标签,只是你需要在命令的末尾指定提交的校验和:

//9fceb02为某个版本的校验和
git tag -a v1.2 9fceb02

共享标签

默认情况下,git push 命令并不会传送标签到远程仓库服务器上。 在创建完标签后你可以运行 git push origin [tagname]显式地推送标签到共享服务器上:

git push origin v1.5

如果想要一次性推送很多标签,也可以使用带有 --tags 选项的 git push 命令:

git push origin --tags

删除标签

要删除掉你本地仓库上的标签,可以使用命令 git tag -d [tagname],例如:

git tag -d v1.0

应该注意的是上述命令并不会从任何远程仓库中移除这个标签,你必须使用 git push [remote]:refs/tags/[tagname] 来更新你的远程仓库。

Git分支

有人把 Git 的分支模型称为它的`‘必杀技特性’’,也正因为这一特性,使得 Git 从众多版本控制系统中脱颖而出。Git 处理分支的方式可谓是难以置信的轻量,创建新分支这一操作几乎能在瞬间完成,并且在不同分支之间的切换操作也是一样便捷。 与许多其它版本控制系统不同,Git 鼓励在工作流程中频繁地使用分支与合并,哪怕一天之内进行许多次。 理解和精通这一特性,你便会意识到 Git 是如此的强大
而又独特,并且从此真正改变你的开发方式。

分支简介

git分支模型如此便捷,关键在于其创建一个分支其实只是创建了一个指向对象的可变指针,如下图:
在这里插入图片描述
v1.0和master是两个分支指针,表示当前分支指向的是哪个校验和版本,而HEAD指针表示我们当前的工作流使用的是哪个指针。
由于 Git 的分支实质上仅是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件,所以它的创建和销毁都异常高效。 创建一个新分支就相当于往一个文件中写入 41 个字节(40 个字符和 1 个换行符)。
这与过去大多数版本控制系统形成了鲜明的对比,它们在创建分支时,将所有的项目文件都复制一遍,并保存到一个特定的目录。 完成这样繁琐的过程通常需要好几秒钟,有时甚至需要好几分钟。所需时间的长短,完全取决于项目的规模。而在 Git 中,任何规模的项目都能在瞬间创建新分支。 同时,由于每次提交都会记录父对象,所以寻找恰当的合并基础(译注:即共同祖先)也是同样的简单和高效。这些高效的特性使得 Git 鼓励开发人员频繁地创建和使用分支。

分支创建

当我们在用git init命令初始化一个仓库时,git会帮我们默认创建一个master分支,所以一般我们都将master分支作为我们项目的主干使用。但我们要知道的是Git 的 “master” 分支并不是一个特殊分支,它就跟其它分支的使用完全没有区别。
我们可以使用git branch 命令来创建一个新的分支:

git branch testing

你可以简单地使用 git log 命令查看各个分支当前所指的对象。 提供这一功能的参数是 --decorate。

git log --oneline --decorate

分支切换

要切换到一个已存在的分支,你需要使用 git checkout 命令:

git checkout testing

这条命令做了两件事。 一是使 HEAD 指回 master 分支,二是将工作目录恢复成 master 分支所指向的快照内容。 在切换分支时,一定要注意你工作目录里的文件会被改变。
想要新建一个分支并同时切换到那个分支上,你可以运行一个带有 -b 参数的 git checkout 命令:

git checkout -b testing

分支合并

我们可以使用git merge 命令来合并两个分支。比如要把dev分支的内容合并至master,可以如下操作:

//先切换至master分支
git checkout master
//请求合并dev分支至master
git merge dev

我们可以通过 git branch --no-merged来查看尚未合并的分支:
在这里插入图片描述
有时候合并操作不会如此顺利。 如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们。 Git 会暂停下来,等待你去解决合并产生的冲突。你可以在合并冲突后的任意时刻使用 git status 命令来查看那些因包含合并冲突而处于未合并状态的文件。你可以打开这些包含冲突的文件然后手动解决冲突。在你解决了所有文件里的冲突之后,对每个文件使用 git add 命令来将其标记为冲突已解决。
当然更简单解决冲突的方式是通过图形化工具来解决冲突。

分支管理

git branch 命令不只是可以创建与删除分支。 如果不加任何参数运行它,会得到当前所有分支的一个列表:
在这里插入图片描述
如果需要查看每一个分支的最后一次提交,可以运行 git branch -v 命令:
在这里插入图片描述
查看所有包含未合并工作的分支,可以运行 git branch --no-merged。
分支合并后,如果你不再需要此分支,可以使用下面的命令删除:

git branch -d [branchname]

分支开发工作流

Git服务器

GitLab

GitLab 是一个数据库支持的 web 应用,多用于公司内部托管代码。

GitHub

GitHub 是最大的 Git 版本库托管商,是成千上万的开发者和项目能够合作进行的中心。 大部分 Git 版本库都托管在 GitHub,很多开源项目使用 GitHub 实现 Git 托管、问题追踪、代码审查以及其它事情。 它也是世界上最好的源码学习网站。

常用git图形工具

tortoiseGit
SourceTree

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值