美文网首页
Git重要命令回顾

Git重要命令回顾

作者: 刘昊2018 | 来源:发表于2017-12-29 12:04 被阅读64次

    摘要

    最近正在重新学习Git版本控制系统,以前对Git的了解不太深入,这次基于对张龙老师的Git实战视频课程的学习,对Git又有了进一步的认识。对于Git的深入学习过程,将通过多篇文章来记录。也分享给正在学习的同学。

    Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.

    这句话来自于Git的官网,大致意思就是说Git是一个开源免费的分布式的版本控制系统,它可以帮助我们处理不论是小项目还是大项目。最重要的是Git的速度和效率非常优秀。

    从官网的介绍我们还可以看到全球知名的互联网公司都在使用Git管理项目,特别是GitHub上,众多的全世界的顶级项目都托管在GitHub上。

    作为程序员来说,如果我们不能很好的掌握Git的操作和使用,我们就不能很好的利用开源世界给我们的帮助,做一些重复造轮子的工作,更何况GitHub上的开源项目都经历了实际生产中的考验。拥有全世界的开发者的pull request。就像张龙老师说的那样。如果你还不会使用Git,那么你就不要写代码了!

    其实说了这么多,大多数程序员对Git还是有所了解,日常工作中也会使用sourcetree等图形化工具来协助代码的拉取和推送。知道一些常用的命令:

    • git init
    • git add
    • git commit
    • git pull
    • git push
    • git branch

    但是,对Git不了解的同学只是在使用命令,如果一旦出现问题,并不知道如何去解决。所以这也是我们为什么要深入去学习Git原理的部分,让Git真正成为工作的利器,而不是畔脚石

    从现在开始,我将从最基础的命令介绍,一步步触及Git的本质。

    创建仓库

    在Git中创建一个版本库使用命令
    git init
    在终端中输入如下命令

    mkdir mygit
    cd mygit
    git init
    initialized empty Git repository in /Users/liuhao/Desktop/mygit/.git/
    

    上述命令表示创建一个名为mygit文件夹并进入,使用命令git init,这样这个普通的文件夹就被Git来管理了。从Git的反馈来理解也是这个意思,初始化了一个空了Git仓库指向了我们刚才创建的mygit文件夹。

    从提示来看,Git还帮我们创建了一个名为.git隐藏文件夹。从感觉上讲,我们会很自然的想到这个.git文件夹就是Git管理的当前这个仓库的版本信息。既然Git告诉了我们有这个文件夹的存在,那么我们索性进去看看到底有些啥东西。

    cd .git
    ls -al
    total 24
    drwxr-xr-x  10 liuhao  staff  340 12 29 11:25 .
    drwxr-xr-x   3 liuhao  staff  102 12 29 11:17 ..
    -rw-r--r--   1 liuhao  staff   23 12 29 11:17 HEAD
    drwxr-xr-x   2 liuhao  staff   68 12 29 11:17 branches
    -rw-r--r--   1 liuhao  staff  137 12 29 11:17 config
    -rw-r--r--   1 liuhao  staff   73 12 29 11:17 description
    drwxr-xr-x  11 liuhao  staff  374 12 29 11:17 hooks
    drwxr-xr-x   3 liuhao  staff  102 12 29 11:17 info
    drwxr-xr-x   4 liuhao  staff  136 12 29 11:17 objects
    drwxr-xr-x   4 liuhao  staff  136 12 29 11:17 refs
    

    这么多,我们先搂两个瞧瞧,其他的目前还不需要了解。

    cat HEAD
    ref: refs/heads/master
    cat config
    [core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
    

    我们可以看到,HEAD文件里面保存的是一个字符串ref: refs/heads/master
    对Git稍有了解的同学都知道,在Git中master指的是主分支,在Git中,当我们创建版本库之后提交文件至版本控制系统,就天生活动在master分支,所以HEAD里面的内容也就不难理解。它指的就是当前所处的分支

    对于config文件,内容是一些参数键值对,也就是说这些参数开用户是可以配置的,我们暂且不去管这些参数,我们来学习Git中第二条命令,在终端中执行如下命令:

    git config --local user.name 'test'
    git config --local user.email 'test@test.com'
    

    通过上诉命令,我们就给当前仓库配置了用户名和用户邮箱。我们再回到config文件中,

    [core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
    [user]
        name = test
        email = test@test.com
    

    可以清楚的看到config文件中多了三行,我们着重来看最后三行

    [user]
        name = test
        email = test@test.com
    

    [user]表示的是用户相关的配置
    name表示的是当前使用这个仓库的人,一般在开发中我们写上自己的姓名。
    email表示的是这样仓库的人的邮箱,一般在工作项目中,写上自己的企业邮箱。

    配置这两个参数的原因我们等会介绍,至少我们现在可以知道这个仓库属于我们自己。

    文件状态

    说了这么多,现在我们的mygit文件夹中除了.git自动生成的文件。还没有其他文件,我们赶快自己创建一个文件来实验吧,毕竟我们都知道Git给我们最直观的体验,就是用来管理文件的

    cd mygit
    echo 'hello 1.txt' > 1.txt
    cat 1.txt
    hello 1.txt
    

    我们在mygit中创建了一个1.txt并查看其内容为hello 1.txt,至此我们完成了文件的创建,那么我们如何把1.txt提交到版本库中呢?说道这里,我们就要介绍Git中最为重要的三个概念了,它们分别是:

    • 工作区
    • 暂存区
    • 版本库

    它们又分别对应三种状态:

    • 已修改
    • 已暂存
    • 已提交

    以上三种状态可以用来描述文件的生命周期。当我们新增或修改文件之后,这个文件就处于已修改的状态,你可以选择将其添加到暂存区,使其文件变成已暂存的状态,需要特别注意的是,此时虽然处于暂存区,但是还没有被纳入版本库,要想把文件纳入版本库,必须在暂存区的基础上将其提交到版本库,此时,文件才属于已提交状态。获取文件的状态,我们可以使用git status命令,下面我们来演示这个过程。

    git status
    On branch master
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    
        1.txt
    
    nothing added to commit but untracked files present (use "git add" to track)
    
    git add 1.txt
    

    当我们输入git status命令之后,Git告诉我们了如下信息:

    • 当前处于主分支。
    • 还没有被版本控制系统追踪的文件 1.txt。
    • 提示我们可以使用git add来暂存1.txt。
    • 当前暂存区没有文件,所以没有可以被提交的文件。
    • 现在出现了一个文件可以被暂存,以致被提交。

    此时输入git add命令,Git并没有反馈,如果没有提示,就说明操作成功,这点Linux的行为。此时我们再次输入git status

    git status
    On branch master
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
    
        new file:   1.txt
    

    此时反馈的内容与git add之前相比,出现了一些变化:

    • 目前依然处于主分支。
    • 有了一些改变可以被提交。
    • 你也可以使用git reset HEAD <file> 将文件从暂存区撤掉,重置为已修改的状态。

    我们按照一条路走到底的思路,利用git commit命令将其提交。

    git commit -m 'init 1.txt'
    master 48a1eb6] 1.txt
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 1.txt
    

    提交文件,使用git commit命令,-m参数为message,填写此次提交信息,需要注意的是,Git推荐也是强制要求我们必须填写message,并且是有用有意义的内容。我们再来摘取提交之后比较重要信息:

    • master 48a1eb6] 1.txt

    其中的一串数字表示的是commit id,为了区分每一次不同的提交,Git会给我们生产一个不唯一的id。这个commit id非常有用,我们在版本回退的时候会使用它。

    此时,我们就走通了一个文件的生命周期的流程。我们使用如下命令来查看当前场景:

    git status
    On branch master
    nothing to commit, working tree clean
    git log
    commit 48a1eb6b7262d68e28b93d51251c750801b76a24
    Author: test <test@test.com>
    Date:   Fri Dec 29 13:18:49 2017 +0800
    
        1.txt
    

    此时,Git首先告诉我们没有可以被提交的内容,也就是说暂存区没有内容,工作区也是干净的,也就是说当前没有修改任何内容。

    再往下,我们来认识一个常用的命令git log,它会告诉我们历史提交记录,这里我们看见了比较熟悉的内容,那就是commid id,author,email。这里的commit id是完整的,我们之前看到的是它的前面几位。需要了解的是,commit id非常不唯一,只需要前面几位就能确定是哪一次提交。其它两个信息是我们自己使用git config命令设置的,它会在git log中记录下来。这时我们就大概能体会到之前设置user的好处了。他告诉了Git是谁在提交。

    版本回滚

    我们知道在Git中,总是有后悔药可以吃的。版本回滚就是一个方面,使用版本回滚,我们可以回到之前的任意一次提交时的状态。
    此时我们做如下修改:

    vi 1.txt
    add 'text'
    cat 1.txt
    hello 1.txt
    text  
    git commit -a -f 'second commit'
    

    此时我们重新修改了文件并做了一次提交,文件变成了两行内容。需要注意的是,这里使用了添加和提交合一的命令:
    git commit -a -m
    使用这条简短命令的前提是,待提交的文件已经被版本控制系统追踪过。
    这时我们查看这次提交:

    git log
    commit 055c5e79b408721a0129d515baa6dd6ad9f8fe27
    Author: test <test@test.com>
    Date:   Fri Dec 29 14:01:33 2017 +0800
    
        secode commit
    
    commit 48a1eb6b7262d68e28b93d51251c750801b76a24
    Author: test <test@test.com>
    Date:   Fri Dec 29 13:18:49 2017 +0800
    
        1.txt
    

    此时如果我们对当前版本修改的内容不满意,就可以切换到之前的版本,使用命令:

    git reset --hard HEAD~n
    git reset --hard HEAD^
    git reset --hard 48a1e
    

    其中后面两种比较常用。但是推荐使用最后一种方式,给定commit id的一部分,就可以任意的切换到对应的分支。
    第一种是将n换成哪一次提交,第二种一个^代表往前推一个版本,在实际使用中,都不太友好。

    需要注意的是,有时候我们希望又切回最新的版本,使用git log又看不到较新版本的commit id,可以使用git reflog命令。

    git reflog
    055c5e7 HEAD@{0}: reset: moving to 055c
    4f01813 HEAD@{1}: reset: moving to HEAD~4
    055c5e7 HEAD@{2}: commit: secode commit
    f52fa35 HEAD@{3}: commit: add
    48a1eb6 HEAD@{4}: commit: 1.txt
    d2cf225 HEAD@{5}: commit: del
    4f01813 HEAD@{6}: commit (initial): init commit
    

    这样会得到每一次版本的commit id,无论当前处于哪个版本。

    后悔药

    介绍两条可以用来恢复操作的命令

    • 将暂存区中的文件回退到已修改状态

      git rm --cached <file>
      
    • 将已修改的文件恢复成上次提交后的内容,也就是把上一次提交后的修改丢弃

       git checkout -- <file>
      

    需要注意的是要将文件的修改丢弃,该文件必须被版本控制系统追踪过。

    分支

    以上,我们已经学习了很多命令,这些命令非常基础,需要我们信手拈来。要做到烂熟于心,只有去不断练习,设计场景
    之所以说基础,因为这些命令只需要死记后就能拿来使用,还没有涉及到太多原理性的内容,但是分支却是Git中最重要且核心的概念,其重要性怎么强调也不为过,正是因为有了分支,我们才有了工程化中最佳Git实践。这一切,都来源于分支的支持。

    分支中的命令

    介绍分支中的命令之前,先将分支涉及的命令做一下概括。

    • git branch
    • git branch *
    • git checkout *
    • git checkout -b *
    • git merge *
    • git merge -d *

    这些命令涉及到

    • 查看分支
    • 创建分支
    • 切换分支
    • 创建并进入该分支
    • 合并分支
    • 删除分支

    介绍分支,我们重新创建一个仓库来实验,终端中输入如下命令:

    mkdir mygit2
    touch 1.txt
    git add .
    git commit -m 'first commit'
    git branch
    * master
    git branch new
    git branch
    * master
    new
    git checkout new
    master
    * new
    

    在介绍以上命令含义时,我们需要明确master分支到底是什么时候被创建的?

    master分支的创建时机是当我们在创建版本库之后,完成一次完整的add,commit操作之后才创建的,并不是版本库一创建就天生存在。也就是说,master分支的创建其实也是懒加载。

    明白了上述这个问题,我们就很清晰理解我们为什么完成一次提交后,再创建其他分支。
    这样,上诉代码的含义就清晰可见了

    git add
    git commit
    // 此时master被创建
    git branch 
    * master
    //此时有且只有一个分支,并且处于master分支
    git branch new 
    * master
     new
    //创建了一个分支名称为new,目前依然处于master分支
    git checkout new
    master
    * new
    //切换到new分支
    

    从以上注释也能理解命令的含义。

    分支的合并操作

    命令 git merge
    分支的合并操作决定了多分支的作用。我们在开发中,除了master分支以外,还会自定义创建其他分支,比如开发新功能的分支,解决Bug的分支,测试分支,线上发布分支等等。正因为有分支合并,我们可以把主分支的代码轻松copy一份,也可以在其他分支进行修改后把差异部分合并到master分支。

    ls -al
    1.txt
    

    可以发现,在new分支上也有了1.txt,这是因为我们创建new分支时,就是基于master分支,也就拥有了和master分支一样的版本库。这时我们增加一行内容:

    vi 1.txt
    'hello'
    git add .
    git commit
    cat 1.txt
    hello
    

    修改文件并提交到new分支的仓库

    git checkout master
    cat 1.txt
    empty
    git merge new
    Updating c6fdc17..c542424
    Fast-forward
     1.txt | 1 +
     1 file changed, 1 insertion(+)
    cat 1.txt            
    hello
    

    特别需要注意的是,这里出现了一个概念Fast-forward。中文翻译叫快速前进,这个概念比较重要,它的背后隐藏着分支合并的原理,这一部分,内容比较多。下次再进行讲解。

    至此我们就完成对new分支修改的内容的合并。

    相关文章

      网友评论

          本文标题:Git重要命令回顾

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