zoukankan      html  css  js  c++  java
  • 3. Git添加/删除/修改命令

    前言

    该文章只是记录了一些自己的见解,可能并不准确,只是为了学习时的一些记录,不喜勿喷,谢谢

    内容比较啰嗦,主要是写该文章时,记录了其学习的过程

    该文章中主要介绍 添加文件,修改文件,删除文件等对应的git命令以及bash命令的区别,以及修改,删除后如何还原等操作。

    1. 添加操作

    该操作在之前已经演示过了, 这里会演示如何从暂存区中移除掉刚才的git add提交

    1.1 正常添加操作

    使用命令 git add,会将新创建的文件交由git来跟踪,进入暂存区

    [root@huangzb mygit]# echo 'hello' > a.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       a.txt
    nothing added to commit but untracked files present (use "git add" to track)
    [root@huangzb mygit]#
    [root@huangzb mygit]# git add a.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       new file:   a.txt
    #
    [root@huangzb mygit]#
     
    

    从上图可知,我们使用git add命令后,会将该文件由未跟踪状态---> 已跟踪状态,当我们再次使用 git status命令后,可以看到 git给我们的提示,有两种选择,要么提交文件,要么将该文件重新回滚到未跟踪的情况。

    1.2 将暂存区文件回滚到未跟踪状态

    使用命令 git reset HEAD [file]

    在上述中,我们通过git add 将新增的文件添加到暂存区,交由git跟踪,如果我们想放弃此次提交,可以使用命令 git reset HEAD [file]的方式,将文件从暂存区回滚到未跟踪状态。如下图

    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       new file:   a.txt
    #
    [root@huangzb mygit]#
    [root@huangzb mygit]# git reset HEAD a.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       a.txt
    nothing added to commit but untracked files present (use "git add" to track)
    [root@huangzb mygit]#
     
    

    有上图可知,当我们使用git reset命令将暂存区文件回滚后,调用git status命令后,又看到了标识 Untracked fiels的情况,表明该文件又重新回到了未跟踪状态。

    2. 修改操作

    2.1 正常修改操作

    为了演示修改操作后的变化,我们先将刚才创建的文件提交,再来修改,看看变化

    先将上述创建的a.txt文件提交

    [root@huangzb mygit]# git status
    # On branch master
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       a.txt
    nothing added to commit but untracked files present (use "git add" to track)
    [root@huangzb mygit]#
    [root@huangzb mygit]# git add .
    [root@huangzb mygit]# git commit -m 'add a.txt file '
    [master 673577c] add a.txt file
    1 file changed, 1 insertion(+)
    create mode 100644 a.txt
    [root@huangzb mygit]# git status
    # On branch master
    nothing to commit, working directory clean
    [root@huangzb mygit]#
     
    

    现在我们来修改一下文件内容,然后添加到暂存区,看看变化

    [root@huangzb mygit]# git status
    # On branch master
    nothing to commit, working directory clean
    [root@huangzb mygit]#
    [root@huangzb mygit]# echo 'hello java' > a.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# cat a.txt
    hello java
    [root@huangzb mygit]# git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #       modified:   a.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@huangzb mygit]#
    [root@huangzb mygit]#
     
    

    可以看出,修改了a.txt文件后,再次调用 git status命令,发现现在有两种提示:

     1. 要么使用 git add 将文件变化添加到暂存区
     2. 要么使用 git checkout -- file 将修改的文件回滚到未修改前
    

    我们先来看看第二种,放弃本次修改

    [root@huangzb mygit]# git checkout -- a.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    nothing to commit, working directory clean
    [root@huangzb mygit]#
    [root@huangzb mygit]#
    [root@huangzb mygit]# cat a.txt
    hello
    [root@huangzb mygit]#
     
    

    由上图可以看出,我们使用了 git checkout -- file命令,将工作空间中的文件变化还原到了最初的情况。因此我们要记住:如何将还未添加到暂存区的文件修改变化,还原到上次最新的工作空间的文件内容?使用 git checkout -- file 命令,注意 -- 后面有个空格,

    我们再来看看第一种情况,将文件变化添加到暂存区

    [root@huangzb mygit]#
    [root@huangzb mygit]# git add .
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       modified:   a.txt
    #
    [root@huangzb mygit]#
     
    

    可以看到,提交到暂存区后,可以看到提示,依然跟添加操作一样,有两种:

    1. 要么使用 git commit命令 提交到本次仓库中
    2. 要么使用 git reset HEAD file 来取消本次修改,即丢弃本次修改

    下面我们不演示直接提交到本地仓库了,因为没有可介绍,我们重点关注,如何将本次修改还原到最初的情况。

    2.2 将工作空间的修改回滚到修改前的状态

    目前工作空间中的文件修改已经提交到了暂存区,因此想还原到上次最新的工作空间状态需要有两步:

    1. 还原本次暂存区的记录
    2. 在工作空间中还原成最初的记录

    因此,我们需要使用两个命令,先使用 git reset 命令还原本次暂存区的记录(如何还原,我们在之前可以看到暂存区只有保留一份记录,且后续操作会覆盖之前的记录,如果想还原,就需要指定分支来从指定分支来还原该记录,如果还没有commit过,就使用使用 git rm --cache来删除了),然后使用 git checkout 根据上次的暂存区数据来还原工作空间的数据,如何操作如下图:

    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       modified:   a.txt
    #
    [root@huangzb mygit]# git ls-files -s
    100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0       a.txt
    100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0       test.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git cat-file -p 3b18e
    hello world
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       modified:   a.txt
    #
    [root@huangzb mygit]#
    [root@huangzb mygit]# git reset HEAD a.txt
    Unstaged changes after reset:
    M       a.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #       modified:   a.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@huangzb mygit]#
    [root@huangzb mygit]# git checkout -- a.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# cat a.txt
    hello
    [root@huangzb mygit]#
     
    

    从上图可以看出,已经使用 git add命令之后,将文件变化让暂存区识别后,如果工作空间想要还原回之前的状态,则需要两步,先使用 git reset HEAD file的方式,将数据从HEAD指针位置还原数据。然后使用 git checkout -- file 的方式,将暂存区的最新数据会显到工作空间,即达到了还原的状态。

    3. 删除操作

    3.1 正常删除操作

    演示一下通过bash命令 rm 来删除已经被git跟踪的文件的情况

    我们先来演示一波:

    [root@huangzb mygit]# ll
    total 8
    -rw-r--r-- 1 root root  6 Mar 17 13:59 a.txt
    -rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    nothing to commit, working directory clean
    [root@huangzb mygit]#
    [root@huangzb mygit]# cat a.txt
    hello
    [root@huangzb mygit]#
    [root@huangzb mygit]# rm a.txt
    rm: remove regular file ‘a.txt’? y
    [root@huangzb mygit]#
    [root@huangzb mygit]# ll
    total 4
    -rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add/rm <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #       deleted:    a.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@huangzb mygit]#
     
    

    由上图可知,我们将上文创建的 a.txt文件通过 bash命令 -- rm 来删除,删除后,我们可以看到有两种情况来处理:

    1. 要么使用git add 来将该变化添加到暂存区
    2. 要么使用 git checkout -- file 来回滚
    

    我们先来看看 第二种情况场景

    [root@huangzb mygit]#
    [root@huangzb mygit]# git checkout -- a.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# ll
    total 8
    -rw-r--r-- 1 root root  6 Mar 17 14:15 a.txt
    -rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
    [root@huangzb mygit]# cat a.txt
    hello
    [root@huangzb mygit]#
     
    

    可以看到,通过 git checkout -- file 的方式,已经将 a.txt 还原回来了

    再来看看第一种情况

    我们再次删除掉 a.txt 文件,然后添加到 暂存区,如下图

    [root@huangzb mygit]# rm -rf a.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add/rm <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #       deleted:    a.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@huangzb mygit]#
    [root@huangzb mygit]# git add a.txt
    warning: You ran 'git add' with neither '-A (--all)' or '--ignore-removal',
    whose behaviour will change in Git 2.0 with respect to paths you removed.
    Paths like 'a.txt' that are
    removed from your working tree are ignored with this version of Git.
     
    * 'git add --ignore-removal <pathspec>', which is the current default,
      ignores paths you removed from your working tree.
     
    * 'git add --all <pathspec>' will let you also record the removals.
     
    Run 'git status' to check the paths you removed from your working tree.
     
    [root@huangzb mygit]#
    [root@huangzb mygit]# git add -A a.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       deleted:    a.txt
    #
    [root@huangzb mygit]#
     
    

    由上图可知,当我们使用 git add a.txt 将删除变化提交到暂存区的时候提示需要添加参数,因为针对删除操作需要提供参数,要么允许暂存区保留删除操作,要么不讲删除操作提交到暂存区。这里我们使用 -A 的方式,将删除操作提交到暂存区,然后通过 git status 查看后,有两种情况处理

    1. 要么使用commit提交到本地仓库
    2. 要么使用 git reset 还原
    

    我们这里就不演示commit了,使用第二种方式,将文件还原,操作如下图

    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       deleted:    a.txt
    #
    [root@huangzb mygit]# git ls-files -s
    100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0       test.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]#
    [root@huangzb mygit]# git reset HEAD a.txt
    Unstaged changes after reset:
    D       a.txt
    [root@huangzb mygit]# git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add/rm <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #       deleted:    a.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@huangzb mygit]# git ls-files -s
    100644 ce013625030ba8dba906f756967f9e9ca394464a 0       a.txt
    100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0       test.txt
    [root@huangzb mygit]# git checkout -- a.txt
    [root@huangzb mygit]# ll
    total 8
    -rw-r--r-- 1 root root  6 Mar 17 14:59 a.txt
    -rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
    [root@huangzb mygit]#
     
    

    从上图操作中我们可以看到,前面使用 git add 操作后,暂存区的a.txt文件已经被删除了。然后使用 git reset命令从HEAD指针所处分支还原了 a.txt到暂存区,最后使用 git checkout -- file 将a.txt文件从暂存区还原了。

    3.2 使用 git rm 命令来进行删除操作

    git rm 命令就是上述使用 bash命令 rm以及后续 git add操作的集合,等同使用一条命令就可以了完成两步操作

    我们先来演示一波,如下图

    [root@huangzb mygit]# ll
    total 8
    -rw-r--r-- 1 root root  6 Mar 17 14:59 a.txt
    -rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git rm a.txt
    rm 'a.txt'
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       deleted:    a.txt
    #
    [root@huangzb mygit]#
     
    

    从上图我们可以看到,通过 git rm 命令后,通过 git status 显示效果,直接提示我们可以进行 commit了,因此该操作是 rm a.txt 以及 git add -A a.txt 操作的组成,后面的操作跟上述的一样,简单写下,不早重复介绍。如下图

    [root@huangzb mygit]# git reset HEAD a.txt
    Unstaged changes after reset:
    D       a.txt
    [root@huangzb mygit]# git checkout -- a.txt
    [root@huangzb mygit]# ll
    total 8
    -rw-r--r-- 1 root root  6 Mar 17 15:09 a.txt
    -rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
    [root@huangzb mygit]#
     
    

    3.3 注意点

    在刚才我们使用 bash命令 rm命令删除后,使用 git add命令添加到暂存区的时候,针对删除操作需要提供一个额外的参数 -A

    4. 移动操作

    4.1 正常移动操作

    我们先来使用正常的 bash命令来移动文件

    新创建一个目录,将该文件移动到新目录中,操作如下:

    [root@huangzb mygit]# mkdir m1 && mv a.txt  m1
    [root@huangzb mygit]#
    [root@huangzb mygit]#
    [root@huangzb mygit]# ll
    total 8
    drwxr-xr-x 2 root root 4096 Mar 20 12:09 m1
    -rw-r--r-- 1 root root   12 Mar 15 21:17 test.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# tree
    .
    ├── m1
    │   └── a.txt
    └── test.txt
     
    1 directory, 2 files
    [root@huangzb mygit]# git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add/rm <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #       deleted:    a.txt
    #
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       m1/
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@huangzb mygit]#
     
    

    由上图可知,我们新创建了一个目录 m1,且将文件 a.txt 移动到了 m1 目录中,我们使用 git status可以看到其实移动文件造成了两步操作,删除原文件,创建新文件等两步,下面我们先提交到暂存区后,看看如何回滚到之前的操作。

    [root@huangzb mygit]# git add -A .
    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       renamed:    a.txt -> m1/a.txt
    #
    [root@huangzb mygit]#
     
    

    从上图可以看出,对于git来说,针对已跟踪文件的移动来说,起始就是一个 renamed操作。现在如果相对该文件进行还原,来看看如何操作

    [root@huangzb mygit]# git reset HEAD a.txt
    Unstaged changes after reset:
    D       a.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       new file:   m1/a.txt
    #
    # Changes not staged for commit:
    #   (use "git add/rm <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #       deleted:    a.txt
    #
    [root@huangzb mygit]# git checkout -- a.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       new file:   m1/a.txt
    #
    [root@huangzb mygit]# git reset HEAD m1/a.txt
    [root@huangzb mygit]# git status
    # On branch master
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       m1/
    nothing added to commit but untracked files present (use "git add" to track)
    [root@huangzb mygit]#
     
    

    由上图可知,其实移动操作,在git中分成了两个步骤,

    1. 删除了 a.txt 文件,
    2. 添加了 m1/a.txt 文件,

    因此如果想要还原到最初的状态,也需要对着两步分别还原,我们知道单独的从一步,从暂存区还原数据,也是需要两步

    1. 使用 git reset 从版本库中更新为最新的数据到暂存区,变相的还原了暂存区的修改
    2. 使用 git checkout 从暂存区中恢复工作目录数据,达到恢复最初数据的目的

    因此,上图,也分别使用了这两步,将 a.txt 进行了还原,同时 看最后的结果,针对新添加的文件,我们已经从暂存区中删除了跟踪,即 m1/a.txt 该文件已经变成了未跟踪文件,此时还原,只要通过bash命令直接删除即可。如下图:

    [root@huangzb mygit]# rm -rf m1
    [root@huangzb mygit]#
    [root@huangzb mygit]# git status
    # On branch master
    nothing to commit, working directory clean
    [root@huangzb mygit]#
     
    

    这样,就完成了正常移动操作的还原步骤

    4.2 使用 git mv 命令来进行移动操作

    同 删除操作一样,同样的针对移动操作,git也提供了 一个 git mv 命令来帮助我们优化bash命令的移动操作。同4.1 而言,我们使用 bash命令 mv 来移动文件后,还需要手动的使用 git add 来将文件变化添加到暂存区,而使用 git mv 命令就可以直接帮我们将变化提交到暂存区。如下图

    [root@huangzb mygit]# ll
    total 8
    -rw-r--r-- 1 root root  6 Mar 21 19:35 a.txt
    -rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
    [root@huangzb mygit]#
    [root@huangzb mygit]# mkdir m2
    [root@huangzb mygit]# git mv a.txt m2/
    [root@huangzb mygit]# tree
    .
    ├── m2
    │   └── a.txt
    └── test.txt
     
    1 directory, 2 files
    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       renamed:    a.txt -> m2/a.txt
    #
    [root@huangzb mygit]#
     
    

    由上图可以看出,直接使用命令 git mv 就达到了上述的效果,下一步就是使用 git commit来进行提交到版本库,这里就不演示了,下面来快速的进行还原,还原操作其实同 4.1 一致,如下图:

    [root@huangzb mygit]# git reset HEAD a.txt
    Unstaged changes after reset:
    D       a.txt
    [root@huangzb mygit]# git checkout -- a.txt
    [root@huangzb mygit]# git reset HEAD m2/a.txt
    [root@huangzb mygit]# git status
    # On branch master
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       m2/
    nothing added to commit but untracked files present (use "git add" to track)
    [root@huangzb mygit]# rm -rf m2/
    [root@huangzb mygit]# tree
    .
    ├── a.txt
    └── test.txt
     
    0 directories, 2 files
    [root@huangzb mygit]# git status
    # On branch master
    nothing to commit, working directory clean
    [root@huangzb mygit]#
     
    

    5. 重命名操作

    重命名操作本质上就是一个 移动操作,快速的使用 git mv 命令来演示一下

    如下图:

    [root@huangzb mygit]# git mv a.txt b.txt
    [root@huangzb mygit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       renamed:    a.txt -> b.txt
    #
    [root@huangzb mygit]#
    [root@huangzb mygit]# git reset HEAD a.txt
    Unstaged changes after reset:
    D       a.txt
    [root@huangzb mygit]# git checkout -- a.txt
    [root@huangzb mygit]# git reset HEAD b.txt
    [root@huangzb mygit]# git status
    # On branch master
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       b.txt
    nothing added to commit but untracked files present (use "git add" to track)
    [root@huangzb mygit]#
    [root@huangzb mygit]# rm -rf b.txt
    [root@huangzb mygit]# ll
    total 8
    -rw-r--r-- 1 root root  6 Mar 21 19:56 a.txt
    -rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
    [root@huangzb mygit]#
     
    

    由上图可知,我们使用 git mv命令 将 a.txt 重命名为 b.txt ,其实还是使用了 git mv 命令,效果跟 4.x步骤一样,还原操作也是一样的。

  • 相关阅读:
    CSS中常用中文字体转Unicode编码表
    CSS自定义字体(@font-face选择符)
    ie7 动态改变select option时,宽度自动变短解决方法
    面试题
    HTML DOM Document 对象
    测试
    复习代码
    Android 极光推送集成
    Android 事件分发
    Android View
  • 原文地址:https://www.cnblogs.com/duguxiaobiao/p/12598599.html
Copyright © 2011-2022 走看看