Lite Git (III) - First Commit

Lite Git (III) - First Commit

前言

本专栏名为Lite Git。主要想与Pro Git对应,后者为Git官方指南,有兴趣,或者想了解更多细节的同学,请移步官网下载PDF版

本专栏主要为了让初出茅庐的同学更快、更合理地掌握Git的基本运用;

同时,本专栏也会介绍一下作为Android开发人员关心的:repo的运用;

本篇是该专栏的第三篇,主要介绍Git仓库的的结构划分,属于比较重要的一节,刚开始了解Git的同学强烈建议了解一下;

在了解了本章节以后,后续的git命令学习就是手到擒来的事情。

此后会完成第一笔提交,并在此过程中进一步加深对Git仓库结构的理解;

结构划分

在介绍使用步骤之前,我认为如下概念需要先介绍一下,这有助于后面命令的记忆与理解;

前面已经提到了工作区(Working Directory)以及git仓库(Repository)的的概念。事实上,在常规Git仓库(即:非裸仓库)下,还有一个暂存区(Staging Area)。那么这三个概念的简介依次如下:

  • working directory 工作区,即git仓库托管的文件内容检出后的工作区域,可以由用户自由查看、编辑、更改。大部分情况下等效于除去.git目录以外的内容,git裸仓库下没有工作区
  • git repository 仓库本身,大部分情况下等效于.git目录(非裸仓库,后者仓库根目录即为仓库本身),其内部是有一套管理、压缩、索引机制,这个对于初学者来说无需过多关注(如果后面有时间会提一提);
  • staging area 我习惯于称之为暂存区(后面将维持此称呼)。在git内部通过一个名为index的文件进行管理(因此部分地方提到index也是指代这个),主要用于一些版本控制过程的中间态的记录,通常是一些待提交的内容的记录。这部分比较难理解,但是对玩转git有很大的帮助。后面会详细讲解;

为了加深记忆,这里使用上一节的demo_client仓库来讲解:

# demo_client 为常规仓库(非裸仓库)
ryan ~/git_demo/demo_client (master) $ ll
total 12
drwxr-xr-x 3 ryan ryan 4096 Oct 27 13:36 ./
drwxr-xr-x 5 ryan ryan 4096 Oct 27 13:36 ../
drwxr-xr-x 7 ryan ryan 4096 Oct 27 13:36 .git/
ryan ~/git_demo/demo_client (master) $

此时:

  • 工作区为空(但不是不存在,git裸仓库下工作区不存在);
  • 仓库非空(结构存在,但内容为空);
  • 暂存区为空(没有index);

提交修改

由于目前demo_client与远端的demo_bare仓库均没有追踪任何文件,因此仓库是空的。

现在,我们借“完成第一笔提交”这一目的,逐步介绍各个阶段下,不同区域的情况,以加深大家对这三个区域的理解:

  1. 首先,我们在demo_client目录下创建一个文件FileA(Linux环境):

    ryan ~/git_demo/demo_client (master) $ touch FileA
    ryan ~/git_demo/demo_client (master) $ ll
    total 12
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 13:44 ./
    drwxr-xr-x 5 ryan ryan 4096 Oct 27 13:36 ../
    drwxr-xr-x 7 ryan ryan 4096 Oct 27 13:36 .git/
    -rw-r--r-- 1 ryan ryan    0 Oct 27 13:44 FileA
    
  2. 然后,我们通过git status查看git的情况:

    #查看.git仓库,依旧没有index文件
    ryan ~/git_demo/demo_client (master) $ ll .git/
    total 40
    drwxr-xr-x 7 ryan ryan 4096 Oct 27 13:45 ./
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 13:44 ../
    -rw-r--r-- 1 ryan ryan   23 Oct 27 13:36 HEAD
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 branches/
    -rw-r--r-- 1 ryan ryan  254 Oct 27 13:36 config
    -rw-r--r-- 1 ryan ryan   73 Oct 27 13:36 description
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 hooks/
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 info/
    drwxr-xr-x 4 ryan ryan 4096 Oct 27 13:36 objects/
    drwxr-xr-x 4 ryan ryan 4096 Oct 27 13:36 refs/
    
    #git status可以查看当前仓库的文件情况
    ryan ~/git_demo/demo_client (master) $ git status
    On branch master
    
    No commits yet
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            FileA
    
    nothing added to commit but untracked files present (use "git add" to track)
    

    可见,git发现了FileA,但是表示自己并未追踪该文件(Untracked

    所以此时:

    • 工作区非空(有FileA);
    • 仓库非空(结构存在,但内容为空);
    • 暂存区为空(没有index);
  3. 接下来,我们要想将FileA提交到git仓库中,则先需要使用git add命令将其添加进暂存区

    #将FileA添加进暂存区
    ryan ~/git_demo/demo_client (master) $ git add FileA
    #查看.git目录情况,发现有了index文件
    ryan ~/git_demo/demo_client (master) $ ll .git/
    total 44
    drwxr-xr-x 7 ryan ryan 4096 Oct 27 13:52 ./
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 13:44 ../
    -rw-r--r-- 1 ryan ryan   23 Oct 27 13:36 HEAD
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 branches/
    -rw-r--r-- 1 ryan ryan  254 Oct 27 13:36 config
    -rw-r--r-- 1 ryan ryan   73 Oct 27 13:36 description
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 hooks/
    -rw-r--r-- 1 ryan ryan  104 Oct 27 13:52 index
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 info/
    drwxr-xr-x 5 ryan ryan 4096 Oct 27 13:52 objects/
    drwxr-xr-x 4 ryan ryan 4096 Oct 27 13:36 refs/
    #再次使用git status查看情况
    ryan ~/git_demo/demo_client (master) $ git status
    On branch master
    
    No commits yet
    
    Changes to be committed:
      (use "git rm --cached <file>..." to unstage)
            new file:   FileA
    
    

    可以看到FileA已经不再是Untracked状态,而是to be committed状态了,说明“新建FileA的行为已经被暂存区记录下来了”;

    所以此时:

    • 工作区非空(有FileA);
    • 仓库非空(结构存在,但内容为空);
    • 暂存区非空(有index,记录了“FileA的创建”);
  4. 最后,我们要将“FileA的创建”这一修改提交进git仓库,这里需要使用git commit命令:

    # git commit -m 可以直接将后面的字符串作为提交信息直接提交,如果不带-m参数,则会弹出默认的文本编辑器(之前我配置的是nano)供用户输入提交信息;
    ryan ~/git_demo/demo_client (master) $ git commit -m "[demo_client]add FileA"
    [master (root-commit) 0dbaef0] [demo_client]add FileA
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 FileA
    # 查看仓库根目录情况
    ryan ~/git_demo/demo_client (master) $ ll
    total 12
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 13:44 ./
    drwxr-xr-x 5 ryan ryan 4096 Oct 27 13:36 ../
    drwxr-xr-x 8 ryan ryan 4096 Oct 27 13:59 .git/
    -rw-r--r-- 1 ryan ryan    0 Oct 27 13:44 FileA
    # 查看.git仓库情况
    ryan ~/git_demo/demo_client (master) $ ll .git/
    total 52
    drwxr-xr-x 8 ryan ryan 4096 Oct 27 13:58 ./
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 13:44 ../
    -rw-r--r-- 1 ryan ryan   23 Oct 27 13:58 COMMIT_EDITMSG
    -rw-r--r-- 1 ryan ryan   23 Oct 27 13:36 HEAD
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 branches/
    -rw-r--r-- 1 ryan ryan  254 Oct 27 13:36 config
    -rw-r--r-- 1 ryan ryan   73 Oct 27 13:36 description
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 hooks/
    -rw-r--r-- 1 ryan ryan  137 Oct 27 13:58 index
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 info/
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 13:58 logs/
    drwxr-xr-x 7 ryan ryan 4096 Oct 27 13:58 objects/
    drwxr-xr-x 4 ryan ryan 4096 Oct 27 13:36 refs/
    # 使用git status查看git管理情况
    ryan ~/git_demo/demo_client (master) $ git status
    On branch master
    Your branch is based on 'origin/master', but the upstream is gone.
      (use "git branch --unset-upstream" to fixup)
    
    nothing to commit, working tree clean
    # 使用git log查看提交信息
    ryan ~/git_demo/demo_client (master) $ git log
    commit 0dbaef0a8d45b36725fe6df20e1f1484709cea1f (HEAD -> master)
    Author: Ryan_ZHENG <*****>
    Date:   Wed Oct 27 13:58:48 2021 +0800
    
        [demo_client]add FileA
    

    所以此时:

    • 工作区非空(有FileA);
    • 仓库非空(有“[demo_client]add FileA”的提交记录);
    • 暂存区非空(有index,记录了“FileA的创建”);
  5. 为了进一步了解这三个区域的关系,现在我们尝试将FileA删除:

    # 直接操作工作区,删除文件FileA
    ryan ~/git_demo/demo_client (master) $ rm FileA
    # 查看仓库根目录,FileA已不存在
    ryan ~/git_demo/demo_client (master) $ ll
    total 12
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 14:07 ./
    drwxr-xr-x 5 ryan ryan 4096 Oct 27 13:36 ../
    drwxr-xr-x 8 ryan ryan 4096 Oct 27 13:59 .git/
    
    # 查看.git目录情况
    drwxr-xr-x 8 ryan ryan 4096 Oct 27 14:07 ./
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 14:07 ../
    -rw-r--r-- 1 ryan ryan   23 Oct 27 13:58 COMMIT_EDITMSG
    -rw-r--r-- 1 ryan ryan   23 Oct 27 13:36 HEAD
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 branches/
    -rw-r--r-- 1 ryan ryan  254 Oct 27 13:36 config
    -rw-r--r-- 1 ryan ryan   73 Oct 27 13:36 description
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 hooks/
    -rw-r--r-- 1 ryan ryan  137 Oct 27 13:58 index
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 info/
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 13:58 logs/
    drwxr-xr-x 7 ryan ryan 4096 Oct 27 13:58 objects/
    drwxr-xr-x 4 ryan ryan 4096 Oct 27 13:36 refs/
    
    # 使用git status查看git管理情况
    ryan ~/git_demo/demo_client (master) $ git status
    On branch master
    Your branch is based on 'origin/master', but the upstream is gone.
      (use "git branch --unset-upstream" to fixup)
    
    Changes not staged for commit:
      (use "git add/rm <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
            deleted:    FileA
    
    no changes added to commit (use "git add" and/or "git commit -a")
    

    可以看到,此时git发现FileA已经被删除,但是由于暂存区还是有FileA的,因此认定“删除FileA”的操作not stagged for commit
    所以此时:

    • 工作区空(FileA已被删除);
    • 仓库非空(有“[demo_client]add FileA”的提交记录);
    • 暂存区非空(有index,记录了“FileA的创建”,但没有记录“FileA的删除”);
  6. 然后照例,要向提交这一改动,我们需要先将“FileA的删除”这一行为添加进暂存区。需要注意的是,由于FileA已不在工作区中了,因此此时git add命令需要带上-A参数:

    # 将“删除FileA”添加进暂存区
    ryan ~/git_demo/demo_client (master) $ git add -A FileA
    # 查看仓库根目录的情况
    ryan ~/git_demo/demo_client (master) $ ll
    total 12
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 14:07 ./
    drwxr-xr-x 5 ryan ryan 4096 Oct 27 13:36 ../
    drwxr-xr-x 8 ryan ryan 4096 Oct 27 14:13 .git/
    # 查看.git目录情况
    ryan ~/git_demo/demo_client (master) $ ll .git/
    total 52
    drwxr-xr-x 8 ryan ryan 4096 Oct 27 14:13 ./
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 14:07 ../
    -rw-r--r-- 1 ryan ryan   23 Oct 27 13:58 COMMIT_EDITMSG
    -rw-r--r-- 1 ryan ryan   23 Oct 27 13:36 HEAD
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 branches/
    -rw-r--r-- 1 ryan ryan  254 Oct 27 13:36 config
    -rw-r--r-- 1 ryan ryan   73 Oct 27 13:36 description
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 hooks/
    -rw-r--r-- 1 ryan ryan   46 Oct 27 14:13 index
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 info/
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 13:58 logs/
    drwxr-xr-x 7 ryan ryan 4096 Oct 27 13:58 objects/
    drwxr-xr-x 4 ryan ryan 4096 Oct 27 13:36 refs/
    # git status查看git管理情况
    ryan ~/git_demo/demo_client (master) $ git status
    On branch master
    Your branch is based on 'origin/master', but the upstream is gone.
      (use "git branch --unset-upstream" to fixup)
    
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            deleted:    FileA
    

    可以看到,此时.git/index文件已更新,且git status显示“FileA的删除”已经从not stagged for commit变为to be committed
    所以此时:

    • 工作区空(FileA已被删除);
    • 仓库非空(有“[demo_client]add FileA”的提交记录);
    • 暂存区非空(有index,记录了“FileA的创建”,也记录了“FileA的删除”);

    注意,此时虽然暂存区非空,而工作区为空,但是两者记录的现象是一致的——没有FileA

  7. 最后,我们使用git commit将“FileA的删除”也提交:

    ryan ~/git_demo/demo_client (master) $ git commit -m "[demo_client]delete FileA"
    [master 0b64004] [demo_client]delete FileA
     1 file changed, 0 insertions(+), 0 deletions(-)
     delete mode 100644 FileA
     
    ryan ~/git_demo/demo_client (master) $ ll
    total 12
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 14:07 ./
    drwxr-xr-x 5 ryan ryan 4096 Oct 27 13:36 ../
    drwxr-xr-x 8 ryan ryan 4096 Oct 27 14:19 .git/
    
    ryan ~/git_demo/demo_client (master) $ ll .git
    total 52
    drwxr-xr-x 8 ryan ryan 4096 Oct 27 14:19 ./
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 14:07 ../
    -rw-r--r-- 1 ryan ryan   26 Oct 27 14:19 COMMIT_EDITMSG
    -rw-r--r-- 1 ryan ryan   23 Oct 27 13:36 HEAD
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 branches/
    -rw-r--r-- 1 ryan ryan  254 Oct 27 13:36 config
    -rw-r--r-- 1 ryan ryan   73 Oct 27 13:36 description
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 hooks/
    -rw-r--r-- 1 ryan ryan   65 Oct 27 14:19 index
    drwxr-xr-x 2 ryan ryan 4096 Oct 27 13:36 info/
    drwxr-xr-x 3 ryan ryan 4096 Oct 27 13:58 logs/
    drwxr-xr-x 9 ryan ryan 4096 Oct 27 14:19 objects/
    drwxr-xr-x 4 ryan ryan 4096 Oct 27 13:36 refs/
    
    ryan ~/git_demo/demo_client (master) $ git status
    On branch master
    Your branch is based on 'origin/master', but the upstream is gone.
      (use "git branch --unset-upstream" to fixup)
    
    nothing to commit, working tree clean
    
    ryan ~/git_demo/demo_client (master) $ git log
    commit 0b64004ae55297fee8ba6453f065a43a9135e5d7 (HEAD -> master)
    Author: Ryan_ZHENG <*****>
    Date:   Wed Oct 27 14:19:08 2021 +0800
    
        [demo_client]delete FileA
    
    commit 0dbaef0a8d45b36725fe6df20e1f1484709cea1f
    Author: Ryan_ZHENG <*****>
    Date:   Wed Oct 27 13:58:48 2021 +0800
    
        [demo_client]add FileA
    

    可以看到,此时git status显示工作区又回到了clean的状态,即工作区仓库暂存区三者记录的情况一致;
    此时:

    • 工作区空(FileA已被删除);
    • 仓库非空(有“[demo_client]add FileA”的提交记录);
    • 暂存区非空(有index,记录了“FileA的创建”,也记录了“FileA的删除”);

    跟上面一样,这里需要注意,此时虽然三者的状态不一样,但是现象是一致的——没有FileA,不同的是,对于仓库而言,记录了FileA的创建于删除两个节点;对于暂存区而言,记录了当前目录存在,但没有任何文件在内;而对于工作区,则只知道没有任何文件;

推送修改

还记得吗?demo_client仓库实际是从demo_bare这个裸仓库克隆过来的。而截至目前,我们在demo_client仓库上的提交还没有同步到demo_bare中。此时,我们需要使用git push这个命令:

# git remote -v查看远端的详细信息
ryan ~/git_demo/demo_client (master) $ git remote -v
origin  /home/ryan/git_demo/demo_bare (fetch)
origin  /home/ryan/git_demo/demo_bare (push)

# git push <remote> <branch>可将<branch>的进度,推送到<remote>仓库的<branch>分支
ryan ~/git_demo/demo_client (master) $ git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 6 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (5/5), 414 bytes | 414.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To /home/ryan/git_demo/demo_bare
 * [new branch]      master -> master

# 到demo_bare仓库所谓路径查看git log信息
ryan ~/git_demo/demo_client (master) $ cd /home/ryan/git_demo/demo_bare
ryan ~/git_demo/demo_bare $ git log
commit 0b64004ae55297fee8ba6453f065a43a9135e5d7 (HEAD -> master)
Author: Ryan_ZHENG <*****>
Date:   Wed Oct 27 14:19:08 2021 +0800

    [demo_client]delete FileA

commit 0dbaef0a8d45b36725fe6df20e1f1484709cea1f
Author: Ryan_ZHENG <*****>
Date:   Wed Oct 27 13:58:48 2021 +0800

    [demo_client]add FileA
ryan ~/git_demo/demo_bare $

至此,demo_client完成了同步demo_bare

总结

三个区域状态的不同,就可以判断出当前工作区文件对于git仓库的状态,并通过git status中不同类别显示:

细心的同学应该已经发现了如下规律:

  • 工作区存在,暂存区不存在,表现为Untracked
  • 工作区不存在,暂存区存在(或者工作区与暂存区内容不一致),表现为Changes not staged for commit:
  • 暂存区存在,仓库不存在(或者暂存区与仓库内容不一致),表现为Changes to be committed:
  • 三者完全一致,则提示nothing to commit, working tree clean,且没有Untracked

事实上,上面的前三种情况是可以任意排列组合的,甚至可以组合出如下两种情况:

  • 三者完全不一致;
  • 暂存区不存在,仓库存在;

这两种属于比较进阶的使用场景下才会出现的,这里仅简单“造”一下环境,后面在讲解git reset的时候会有更多示例;

  • 三者完全不一致

    # 创建一个FileB文件,内容为bbb
    ryan ~/git_demo/demo_client (master) $ echo "bbb" > FileB
    
    # 查看内容无误
    ryan ~/git_demo/demo_client (master) $ cat FileB
    bbb
    
    # git status查看FileB状态为Untracked
    ryan ~/git_demo/demo_client (master) $ git status
    On branch master
    Your branch is based on 'origin/master', but the upstream is gone.
      (use "git branch --unset-upstream" to fixup)
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            FileB
    
    nothing added to commit but untracked files present (use "git add" to track)
    
    # 将FileB添加进暂存区
    ryan ~/git_demo/demo_client (master) $ git add FileB
    
    # 再次使用git status查看,此时工作区与暂存区进度一致,与仓库不一致
    ryan ~/git_demo/demo_client (master) $ git status
    On branch master
    Your branch is based on 'origin/master', but the upstream is gone.
      (use "git branch --unset-upstream" to fixup)
    
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            new file:   FileB
    
    
    # 修改FileB内容为bbbbbb
    ryan ~/git_demo/demo_client (master) $ echo "bbbbbb" > FileB
    
    # 查看内容无误
    ryan ~/git_demo/demo_client (master) $ cat FileB
    bbbbbb
    
    # 再次使用git status查看,此时工作区与暂存区进度不一致,与仓库也不一致
    ryan ~/git_demo/demo_client (master) $ git status
    On branch master
    Your branch is based on 'origin/master', but the upstream is gone.
      (use "git branch --unset-upstream" to fixup)
    
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            new file:   FileB
    
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
            modified:   FileB
    
    
  • 暂存区不存在,仓库存在;

    #接着上方的环境继续
    ryan ~/git_demo/demo_client (master) $ git status
    On branch master
    Your branch is based on 'origin/master', but the upstream is gone.
      (use "git branch --unset-upstream" to fixup)
    
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            new file:   FileB
    
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
            modified:   FileB
    # 删除FileB,使仓库与工作区都不存在FileB
    ryan ~/git_demo/demo_client (master) $ rm FileB
    # git status查看
    ryan ~/git_demo/demo_client (master) $ git status
    On branch master
    Your branch is based on 'origin/master', but the upstream is gone.
      (use "git branch --unset-upstream" to fixup)
    
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            new file:   FileB
    
    Changes not staged for commit:
      (use "git add/rm <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
            deleted:    FileB
    

最后来张图:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值