美文网首页
Git基础教程(入门教程)

Git基础教程(入门教程)

作者: 科研者 | 来源:发表于2020-02-19 20:11 被阅读0次

    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. 相关文章

    相关文章

      网友评论

          本文标题:Git基础教程(入门教程)

          本文链接:https://www.haomeiwen.com/subject/fvkzfhtx.html