Git基础教程(入门教程)

1. 前言

本文是 Git 入门级教程,针对的是那些不会使用git的人群;通过该教程,能让你循序渐进地掌握 Git 的基本概念、基本操作流程 和 常用命令;

如果你已经会了 Git 的基本操作,希望在使用git时作为手册去查询,那你可以查看我的另一篇文章Git命令大全

如果你在使用Git中遇到了难题,你可以参考 Git技巧和问题解决方案

2. 为什么使用Git

详情请参考选择Git的理由

3. 为什么使用命令行

Git 有2种使用方式:

  • 命令行方式;
  • 可视化界面的 GUI 方式;

本文中,将使用命令行方式,理由如下:

  • 命令行模式能够进行Git的所有操作;而 GUI 方式只能进行较常用的Git操作;如果你会命令行的方式,那 GUI 的方式也就会了,反之,则不成立;
  • GUI 方式的 Git 软件太多,不同的人喜欢的可能不一样,也不一定都装了 GUI 的Git,但每个人基本上都会有命令行工具,如:Mac 系统里有 Terminal(终端),Windows 系统有 CMD、PowerShell 等等;

4. 安装

安装 Git 命令行工具:

  • Windows系统:从 https://git-scm.com/downloads 下载并安装 Git命令行工具
  • MacOS系统:
    • 方式1:

      1. 打开终端;(如果找不到终端软件,可点击 屏幕右上角的放大镜,然后输入“终端”来查找并打开终端软件)
      2. 执行命令:xcode-select --install ;按照提示操作安装 xcode 命令行工具,如果让输入密码,就输入 电脑的开机密码;
    • 方式2:如果你的电脑上已经安装了 brew命令(Homebrew),你也可以用 brew 安装;安装方式如下,在终端中执行如下命令:

      brew install git
      

5. 配置

安装Git后,使用Git之前,需要先对Git做一些常用的信息的配置;

配置工作只需一次,以后升级时还会沿用现在的配置。当然,如果需要,你随时可以用相同的方式修改已有的配置。

5.1. 用户信息

第一个要配置的是你个人的用户名称和电子邮件地址。这两条配置很重要,每次 Git 提交时都会携带这两条信息,用于说明是谁提交了代码:

git config --global user.name "郭斌勇"
git config --global user.email guobinyong@qq.com

5.2. 文本编辑器

接下来要设置的是默认使用的文本编辑器。Git 需要你输入一些额外消息的时候,会自动调用一个外部文本编辑器给你用。默认会使用操作系统指定的默认编辑器,一般可能会是 Vi 或者 Vim。如果你有其他偏好,比如 Emacs 的话,可以重新设置:

git config --global core.editor emacs

5.3. 差异分析工具

还有一个比较常用的是,在解决合并冲突时使用哪种对比工具。
比如要改用 vimdiff 的话:

git config --global merge.tool vimdiff

Git 可以理解 kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,和 opendiff 等合并工具的输出信息。当然,你也可以指定使用自己开发的工具;

5.4. 查看配置信息

要检查已有的配置信息,可以使用如下命令:

git config --list

有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如 /etc/gitconfig~/.gitconfig),不过最终 Git 实际采用的是最后一个

也可以直接查阅某个环境变量的设定,只要把特定的名字跟在后面即可,像这样:

git config user.name

6. 基本操作

6.1. 获得Git仓库

有两种获得Git仓库的方法:

  1. 在现存的目录下创建新的Git仓库。
  2. 从已有的Git仓库克隆新的镜像仓库。

6.1.1. 在现存的目录下创建新的Git仓库

要对现有的某个项目开始用 Git 管理,只需到此项目的根目录,执行如下命令来创建并初始化Git仓库:

git init

初始化后,在当前目录下会出现一个名为 .git 的目录,Git 仓库的所有信息都包含在该目录中。

6.1.2. 从已有的仓库克隆

如果Git仓库已经存了,那我们可以通过如下命令将该仓库克隆到本机上:
命令格式:

git clone [url]

示例:

git clone https://gitee.com/guobinyong/GitTest.git

注意:如果克隆的是私有仓库,可能会弹出对话框让输入的用户名和密码,输入被克隆的仓库的用户名和密码即可

这会在当前目录下创建一个名为 GitTest 的目录,其中包含一个 .git 的目录,用于保存仓库的所有信息。

如果想指定克隆到本机的仓库的名字,可以使用如下命令格式:

git clone [url]  [仓库名字]

示例:

git clone https://gitee.com/guobinyong/GitTest.git  Test

6.2. 基本概念

我们先来理解下Git 工作区、暂存区和版本库概念

  • 工作区:就是你在电脑里能看到的目录。
  • 仓库:工作区有一个隐藏目录 .git,它不属于工作区,而是Git的仓库。它里面存放着Git仓库的所有数据;
  • 暂存区:英文叫 stage 或 index ,一般存放在仓库(.git 目录)下的 index 文件(.git/index)中,所以有时我们也会把暂存区也叫作索引(index)。
  • 版本库:版本库是仓库中用来存放Git版本(提交记录)的地方,

下图展示了仓库、版本库、暂存区 和 工作区 之间的关系:


工作区暂存区版本库之间的关系

6.3. 提交版本

要把更改添加到版本库,需要两步:

  1. git add 命令把更改添加到暂存区;
  2. git commit 命令将暂存区中的所有内容提交到 版本库,生成新的版本节点;

下面具体演示下操作步骤:

  1. 在项目目录下创建一个文件 file1.txt,内容如下:
a
a
a
a
a
  1. 查看一下当前工作区的状态
git status
git_status_1

输出结果提示 file1.txt 未被跟踪;

  1. 使用如下命令将 file1.txt 文件添加到暂存区
git add file1.txt 

若想一次添加所有的文件,可以使用以下方式之一:

  • git add . : 添加新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件;在Shell里,后面的 . 代表当前目录, 所以相当于将当前目录传给了 add 命令;
  • git add * :添加所有非隐藏的的文件的变化;* 是 shell 语言中的通配符,能匹配所有非隐藏的文件 和 目录,所以相当于将匹配的到文件和目录都传给了 add 命令;
  • git add -A :添加所有变化;
  • git add -u : 添加被修改(modified)和 被删除(deleted)文件,不包括新文件(new);

再查看一下工作区的状态


git_status_2

file1.txt 未跟踪的信息已经没有了;但列出了一些将被提交的文件;

  1. 我们再次修改一下 file1.txt 的内容,将第3行换成 b,内容如下:
a
a
b
a
a

然后再查看一下工作区的状态:


git_status_3

又多了一条新提示,提示我们有一个 file1.txt 文件的修改没有被暂存;

  1. 再次添加变更
git add file1.txt 

add 是个多功能命令,根据目标文件的状态不同,此命令的效果也不同:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等;

再查看一下工作区的状态


git_status_2

跟第一次执行 git add file1.txt 后的结果一样,这意味着 对同一个文件暂存多次变更,git 会合并多次变更,视为一个变更;

  1. 用如下命令将暂存区中的变更提交到版本库,并为这次提交创建一个新的版本;
git commit

这种方式会启动文本编辑器以便输入本次提交的说明,如下图。(默认会启用 shell 的环境变量 $EDITOR 所指定的软件,一般都是 vim 或 emacs。当然也可以使用 git config --global core.editor 命令设定你喜欢的编辑软件。)

git_commit_1

另外也可以用 -m 参数后跟提交说明的方式,在一行命令中提交更新:

git commit -m “说明文字"

Git 提供了一个跳过使用暂存区域的方式,只要在提交的时候,给 git commit 加上 -a 选项 git commit -a ,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤:

git commit -a -m ‘文字说明'

提交完成后,输出的日志如下:


git_commit_1_日志

查看一下工作区的状态,如下:


git_status_4

以上这些步骤就演示了将变更从工作区添加到版本库的过程;

6.4. 查看提交历史

我们可通过 log 命令来查看提交的历史;

git log
git_log_1

以 ASCII 图形的方式查看提交历史

git log --graph
git_log_1_graph

最近的更新排在最上面。每次更新都有一个 SHA-1 校验和、作者的名字和电子邮件地址、提交时间,最后缩进一个段落显示提交说明。

有时候图形化工具更容易展示历史提交的变化,随 Git 一同发布的 gitk 就是这样一种工具。它是用 Tcl/Tk 写成的,基本上相当于 git log 命令的可视化版本,凡是 git log 可以用的选项也都能用在 gitk 上。在项目工作目录中执行 gitk 命令后,就会启动图 2-2 所示的界面。

Gitk效果图

上半个窗口显示的是历次提交的分支祖先图谱,下半个窗口显示当前点选的提交对应的具体差异。

6.5. 推送数据到远程仓库

目前,我们新提交的所有数据都只是存放在本地的版本库(.git目录)中,远程仓库中还没有这些数据;我们可以查看一下远程仓库中,确定下;

Git 跟 Subversion 不同, Subversion 中只要一提交,数据就会被推到远程仓库中了;造成这些区别的原因是 Git 是布式的版本控制系统,而 Subversion 是集中式的版本控制系统;

集中式
分布式

通过 push 命令,可把本地仓库中的数据推送到远程仓库:

git push
git_push_1

此时,可以查看一下远程仓库中,看是否已经包含了我们的新提交;

6.6. 拉取远程仓库中的更新

如果有其他人往远程远程仓库上推送了新的提交,我们可以执行以下命令来获取新的提交:

git pull

6.7. 忽略某些文件

有时候我们可能想忽略一些文件,比如:node_mode.idea 等等,但是,在执行 statusadd 命令时,总是显示这些文件,甚至一不小心就提交了这些文件;这时我们可以在工作区根目录下创建一个名为 .gitignore 的文件,在该文件中列出要忽略的文件模式;这样,Git 就不会在跟踪和显示这些文件了;

文件 .gitignore 的格式规范如下:

  • 所有空行或者以注释符号 # 开头的行都会被 Git 忽略。
  • 在一行的末尾添加注释,会使该行被Git忽略,所以注释只能独占一行,不能添加在行的末尾;
  • 可以使用标准的 glob 模式匹配。
  • 匹配模式最后跟反斜杠(/)说明要忽略的是目录。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。

所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。

.gitignore 文件的例子:

# 此为注释 – 将被 Git 忽略

# 忽略所有 .a 结尾的文件
*.a

# 但 lib.a 除外
!lib.a

# 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
/TODO

# 忽略 build/ 目录下的所有文件
build/

# 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
doc/*.txt

7. 分支

与 Subversion 不同 Git 中的分支,其实本质上仅仅是个指向 commit 对象的可变指针,它总是指向最后一次的提交对象。在创建仓库时,Git 会自动创建一个名叫 master 的默认分支;

7.1. 查看分支

git branch
git_branch_1

* 标记的分支是当前所在的分支;

7.2. 创建分支

创建一个名叫 dev 的分支

git branch dev

再查看一下分支


git_branch_2

你会发现多了一个 dev 分支;但当前仍处在 master 分支下;也就是说,用 branch 创建新分支时,并不会自动切换到新分支上;

7.3. 切换分支

我们可以用如下命令切换分支:

git checkout dev
git_checkout_1

验证一下是否切换过去


git_branch_3

7.4. 创建并切换分支

创建分支,再切换过去,需要两步,如果想一步完成,也是可以的,只需要用带 -b 选项的 checkout 命令即可:

git checkout -b bug

验证一下


git_branch_4

发现,已经创建了一个 bug 分支,并且也已经切换到 bug 分支上了;

7.5. 分支共用工作区

  1. 在 bug 分支下新增一个 file2.txt 文件,内容如下:
b
b
b
b
b
  1. 将该文件添加到暂存区,并提交;
git add -A
git commit -m "版本2" 
  1. 切换到 master 分支
git checkout master

再查看一下工作区里的内容


ls_1

你会发现,刚才建的那个文件 file2.txt 没有了,因为 master 下没有 file2.txt 文件,file2.txt 在 bug 分支下;

这也说明:

  • 分支 是共用 工作区的;
  • 切换分支时,Git 会自动将工作区里的内容置为当前分支的内容;

7.6. 查看所有分支的提交历史

git log 命令默认只能查看指定分支的提交历史,可视化命令 gitk 也是,如果想查看所有分支的提交历史,可以给 git log 或者 gitk 添加 --all 选项;如下:

git log --all

可视化界面查看

gitk --all

git log --all的输出结果如下:

git_log_2

其中 HEAD -> master 表示当前在 master 分支下,HEAD 表示当前工作区对应的哪个分支 或 提交;

从输出结果中可以看到 master 和 dev 分支还指向同一个提交,而 bug 分支 指向另一个提交;这是因为创建 dev 和 bug 分支时,是处在 master 分支下,创建的新分支会自动 和 当时所在分支 指向同一提交;所以 master 和 dev 分支还指向同一个提交,而后来 bug 分支里单独提交一个版本,所以 bug 分支指向了另一个提交;

7.7. 分支只是一个指针并且共享共同的历史

如果没做切换,当前还是在 master 分支;

  1. 接下来我们在 master 分支里更改一下 file1.txt 的内容,将 第3行 的内容改成 a3,如下:
a
a
a3
a
a
  1. 暂存并提交这次更改,这次我们使用一个快捷的命令
git commit -a  -m "版本3"

添加 -a 选项可以自动暂存 所有已跟踪的文件(被修改(modified)和 被删除(deleted)文件,但不包括新文件(new)),并直接提交;

  1. 查看一下全部分支的提交历史 git log --graph --all --oneline,其中 --oneline 选项是将提交信息放在一行显示;
    git_log_3

从输出结果中可以看到,master 分支指向了刚才提交的新版本 6dad279 版本3,此时 master、dev、bug 分支都指向了不同的提交,但是,它们的版本历史中都有 2a40918 版本1,这是它们共享的提交对象;

并且从结果中也可以看到:
整个仓库的提交历史只有一个,但仓库中可以有多个分支(如:master、dev、bug ),而每个分支都会指向一个提交;所以,在 Git 中,分支只是一个指针,对提交的一个引用,不同分支间可以有共同的提交历史;

7.8. 合并分支

为了给大家演示一下冲突,我们先制造一些冲突;

  1. 切换到 bug 分支 git checkout bug
  2. file1.txt 文件的第3行改成 a4 ,内容如下:
a
a
a4
a
a
  1. 暂存并提交改动 git commit -a -m "版本4"
  2. 将 master 分支的变更合并到 当前分支(bug分支):
    合并分支用 merge 命令,如下:
git merge master
git_merge

从输出中,我们可以看到,合并失败了,因为 file1.txt 文件冲突了;如果没有冲突,合并就自动完成,并会弹出文本编辑器让你输出此次合并的提交信息;

为什么 file1.txt 文件会冲突了呢?
因为 我们在 master 和 bug 分支下都改了第3行的内容,所以冲突了;

什么情况下才会冲突?

两个分支修改了同一文件的同一位置(简单来说,就是修改的内容有交叉)就会导致合并时产生冲突,如果修改的是不同文件 或者 是同一文件的不同位置,也不会导致冲突;

7.9. 查看冲突内容

我们可以使用如下命令查看冲突的内容

git diff
git_diff

输出中显示出了冲突的文件file1.txt,和冲突的内容,其中 <<<<<<< 之上 和 >>>>>>> 之下的内容是共同的内容,非冲突的内容; <<<<<<<======= 之间是当前分支中冲突的内容, =======>>>>>>> 之间是其它分支中冲突的内容;

我们也可以直接在编辑器中查看冲突的文件内容:


vscode_1

7.10. 解决冲突

由于语义的复杂性,Git 目前还不会帮我们自动解决冲突,我们需要自己来解决;

如果此时我们想终止合并,可以使用如下命令:

git merge --abort

如果我们要继续合并,需要先解决冲突,解决冲突的方法如下:

  1. 根据需要决定如何保留和更改冲突的内容;
  2. 移除冲突的标记文行 <<<<<<<=======>>>>>>>
  3. 使用 add 命令将冲突标记为已解决 git add file1.txt 或者 直接标识所有 git add .
  4. 提交变更 git commit
    git_commit_2.png

    这会弹出文本编辑器让你输出此次合并的提交信息,里面默认有表达合并的操作的提交信息,使用默认的即可;

当冲突解决了并提交后,合并操作也就完成了;此时查看一下整个仓库的版本历史:

git log --all --graph
git_log_4

从输出结果中可以看到,合并会产生一个新的提交对象 ebb0d5b95a3e30127379a862de42ad96812d0720 ,并且分支当前分支(bug分支)已经指向了这个新的合并对象;但 master 分支仍然指向的是原来的提交对象 9e32b1556d3259e9193b19942ef76756c7e6afd3 版本3,因为我们是将 master 分支的内容 合并到 当前分支(bug分支),合并改变的是当前分支,并不会影响 master 分支;

7.11. 删除分支

如果我们想删除一个分支(比如 dev 分支),我们可以使用如下命令:

git branch -d dev

8. 获取帮助

想了解 Git 的各式工具该怎么用,可以阅读它们的使用帮助,方法有三:

  • $ git help [命令]
  • $ git [命令] --help
  • $ man git

比如,要学习 config 命令可以怎么用,运行:

$ git help config

帮助文档采用BNF语法格式描述规范描述命令行的语法,BNF语法格式的元字符及其含义如下:
[ ]:可选内容;
< >:必须给出内容;
{ }:可重复0至无数次的内容;
a|b|c:多选一;
:可以有多个;

备注:关于BNF的详细内容可参考《语法格式描述规范BNF和ABNF

9. Git和Subversion的命令的对比

详情请看Git和Subversion的命令的对比

10. 相关文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,706评论 4 366
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,002评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,462评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,375评论 0 216
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,763评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,849评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,033评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,768评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,490评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,734评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,204评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,566评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,227评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,137评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,934评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,926评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,774评论 2 274

推荐阅读更多精彩内容

  • 一、基本概念: 注:对于git的分布式概念及其优点,不重复说明,自己百度或谷歌。本文中涉及到指令前面有$的,在cm...
    大厂offer阅读 1,336评论 0 3
  • 还是老规矩,这篇看完后,还是学不会git版本控制的,你来砍我 是兄弟就来砍我吧!!! Git是分布式版本控制系统,...
    Zteen阅读 3,044评论 0 6
  • Git 是目前最流行的分布式版本控制系统之一。 版本控制指的是,记录每次版本变更的内容和时间等细节,保留各版本之间...
    神齐阅读 1,328评论 0 7
  • 为什么选择GIT? Git自从2005年问世以来,已经逐步成为本地和分布环境下版本控制的事实标准。Git最早由Li...
    技匠阅读 10,734评论 12 235
  • 上周五12号,腾讯又为“亲儿子”小程序打开了一个流量入口,开放了小程序“搜索联想区”功能,用户可在搜索时仅输入一个...
    流明咖啡店阅读 271评论 0 0