• git rm命令 & git reset和checkout区别


    原文:https://blog.csdn.net/qq_42780289/article/details/98353792

       https://segmentfault.com/a/1190000006185954

    一、git rm 命令使用

    Git 本地数据管理,大概可以分为三个区:

    工作区(Working Directory):是可以直接编辑的地方。

    暂存区(Stage/Index):数据暂时存放的区域。

    版本库(commit History):存放已经提交的数据。

    工作区的文件 git add 后到暂存区,暂存区的文件 git commit 后到版本库。

    1.1 rm 命令

    1. 作用: 删除工作区的文件。

    执行删除命令:

    $ rm test.txt

    查看状态(成功删除工作区文件):

    $ 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:    test.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")

    rm 命令只是删除工作区的文件,并没有删除版本库的文件,想要删除版本库文件还要执行下面的命令:

    $ git add test.txt
    $ git commit -m "delete test"

    2. 结果: 删除了工作区和版本库的文件。

     

    1.2 git rm 命令

    1. 作用: 删除工作区文件,并且将这次删除放入暂存区。

    2. 注意: 要删除的文件是没有修改过的,就是说和当前版本库文件的内容相同。

    执行删除命令:

    $ git rm test.txt
    rm 'test.txt'

    查看状态(成功删除了工作区文件,并且将这次删除放入暂存区。):

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

    然后提交:

    $ git commit -m "delete test"
    [master f05b05b] delete test
     1 file changed, 3 deletions(-)
     delete mode 100644 test.txt

    成功删除了版本库文件。

    3. 结果: 删除了工作区和版本库的文件,因为暂存区不可能有该文件(如果有意味着该文件修改后 git add 到暂存区,那样 git rm 命令会报错,如下面的情况)。

    1.3 git rm -f 命令

    1. 作用: 删除工作区和暂存区文件,并且将这次删除放入暂存区。
    2. 注意: 要删除的文件已经修改过,就是说和当前版本库文件的内容不同。

    • test文件修改过还没 git add 到暂存区
    $ git rm test.txt
    error: the following file has local modifications:
        test.txt
    (use --cached to keep the file, or -f to force removal)
    • test文件修改过已经 git add 到暂存区
    $ git add test.txt
    $ git rm test.txt
    error: the following file has changes staged in the index:
        test.txt
    (use --cached to keep the file, or -f to force removal)

    可见文件修改后不管有没有 git add 到暂存区,使用 git rm 命令删除都会报错。

    • 解决方法

    执行删除命令:

    $ git rm -f test.txt
    rm 'test.txt'

    查看状态(成功删除工作区和暂存区文件,并且将这次删除放入暂存区。):

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

    然后提交:

    $ git commit -m "delete test"
    [master 9d5d2d2] delete test
     1 file changed, 3 deletions(-)
     delete mode 100644 test.txt

    成功删除了版本库文件。

    3. 结果: 删除了工作区、暂存区和版本库的文件。

    1.4 git rm --cached 命令

    1. 作用: 删除暂存区文件,但保留工作区的文件,并且将这次删除放入暂存区。

    执行删除命令:

    $ git rm --cached test.txt
    rm 'test.txt'

    查看状态(成功删除暂存区文件,保留工作区文件,并且将这次删除放入暂存区,注意这里文件取消了跟踪):

    $ git status
    On branch master
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
    
            deleted:    test.txt
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    
            test.txt

    然后提交:

    $ git commit -m "delete test"
    [master 223d609] delete test
     1 file changed, 3 deletions(-)
     delete mode 100644 test.txt

    成功删除了版本库文件。

    2. 结果: 删除了暂存区和版本库的文件,但保留了工作区的文件。如果文件有修改并 git add 到暂存区,再执行 git rm --cached 和 git commit,那么保留的工作区文件是修改后的文件,同时暂存区的修改文件和版本库的文件也被删了。

    二、git的reset和checkout区别

    原文:https://segmentfault.com/a/1190000006185954

    HEAD、Index、Working Directory

    Git里有三个区域很重要

    1. HEAD 指向最近一次commit里的所有snapshot
    2. Index 缓存区域,只有Index区域里的东西才可以被commit
    3. Working Directory 用户操作区域

    下图解释了这三个区域的状态的变化过程:

    初始状态

    当你checkout分支的时候,git做了这么三件事情

    1. 将HEAD指向那个分支的最后一次commit
    2. 将HEAD指向的commit里所有文件的snapshot替换掉Index区域里原来的内容
    3. 将Index区域里的内容填充到Working Directory里

    所以你可以发现,HEAD、Index、Working Directory这个时候里的内容都是一模一样的。

    注意:一般会误解为,Index中的内容是空的,只有git add后才会有东西。实际上不是,Index里一直是有东西的。

    所以,Git的所有操作就是对这三个区域的状态(或内容)的操作。

    Changed

    如果你在Working Directory里修改了文件,git会发现Working Directory里的内容和Index区域里的内容不一致了。

    这个时候git status的结果是:

    # Changes not staged for commit:

    Staged

    一个文件仅仅changed是不能被commit的,Git要求只能提交Index里的东西。

    所以需要git add。这个命令的意思是,把Changed的文件的内容同步到Index区域里。这样Working Directory和Index区域的内容就一致了。这个过程被称之为stage

    这个时候git status的结果是:

    # Changes to be committed:

    Committed

    最后,你就可以提交了

    git commit

    这样,就把HEAD的状态和Index以及Working Directory形成一致了。

    reset

    reset是用来修改提交历史的,想象这种情况,如果你在2天前提交了一个东西,突然发现这次提交是有问题的。

    这个时候你有两个选择,要么使用git revert(推荐),要么使用git reset。

     上图可以看到git reset是会修改版本历史的,他会丢弃掉一些版本历史。

    而git revert是根据那个commit逆向生成一个新的commit,版本历史是不会被破坏的。

    已经push到远程仓库的commit不允许reset

    上面已经讲了,git reset是会丢弃掉commit的。

    如果commit已经被push到远程仓库上了,也就意味着其他开发人员就可能基于这个commit形成了新的commit,这时你去reset,就会造成其他开发人员的提交历史莫名其妙的丢失,或者其他灾难性的后果。

    因此,一旦commit已经被push到远程仓库,那么是坚决不允许去reset它的。

    不带文件参数的reset

    前面章节已经说道Git有三个区域,Git的所有操作实际上是在操作这三个区域的状态(或内容)。

    git reset配合不同的参数,对这三个区域会产生不同的影响。

    reset实际上有3个步骤,根据不同的参数可以决定执行到哪个步骤(--soft--mixed--hard)。

    1. 改变HEAD所指向的commit(--soft)
    2. 执行第1步,将Index区域更新为HEAD所指向的commit里包含的内容(--mixed)
    3. 执行第1、2步,将Working Directory区域更新为HEAD所指向的commit里包含的内容(--hard)

    注意

    –mixed是默认参数,也就是说执行reset的时候不给就认为是--mixed

    下表说明了三种形式的git reset所产生的不同效果。

    target代表想要将git指向到哪个commit

    working index HEAD target         working index HEAD
    ----------------------------------------------------
      A       B     C    D     --soft   A       B     D
                               --mixed  A       D     D
                               --hard   D       D     D
                               --merge (disallowed)
    
    working index HEAD target         working index HEAD
    ----------------------------------------------------
      A       B     C    C     --soft   A       B     C
                               --mixed  A       C     C
                               --hard   C       C     C
                               --merge (disallowed)

    带文件参数的reset

    上面讲到的git reset实际上不带参数的,如果带上文件参数,那么效果会是怎样的?

    1. HEAD不会动
    2. 将那个commit的snapshot里的那个文件放到Index区域中

    需要注意的是带文件参数的git reset没有--hard, --soft这两个参数。只有--mixed参数。

    unstage

    下面这两个命令是一样的,都是reset到HEAD上。

    git reset file.txt
    git reset --mixed HEAD file.txt

    这个例子的意义在于,unstage file,仔细想一想是不是这样?当你把一个文件stage到Index区域里后后悔了,那么只需要把Index区域里的这个文件恢复到最近一次commit的状态(也就是HEAD),那就相当于unstage了。

    恢复到历史版本

    下面这个命令就是将某个文件恢复到历史版本上。

    reset eb43bf file.txt

    这个例子的意思在于,把某个文件恢复到Index区域里,然后直接commit,这样就等于把这个文件恢复到历史版本了,这样依赖你都不需要去改动Working Directory了。

    checkout

    前面讲到checkout是会修改HEAD的指向,变更Index区域里的内容,修改Working Directory里的内容。

    这看上去很像reset --hard,但和reset --hard相比有两个重要的差别

    1. reset会把working directory里的所有内容都更新掉
    2. checkout不会去修改你在Working Directory里修改过的文件
    3. reset把branch移动到HEAD指向的地方
    4. checkout则把HEAD移动到另一个分支

    第二个区别可能有点难以理解,举例来说:假设你有两个分支master和develop,这两个分支指向不一样的commit,我们现在在develop分支上(HEAD指向的地方)

    如果我们git reset master,那么develop就会指向master所指向的那个commit。

    如果我们git checkout master,那么develop不会动,只有HEAD会移动。HEAD会指向master。看图:

    带文件参数

    当执行git checkout [branch] file时,checkout干了这件事情:

    1. 更新了index区域里file文件的内容
    2. 更新了working directory里file文件的内容

    总结reset和checkout

                             head    index   work dir  wd safe
    Commit Level
    reset --soft [commit]    REF     NO      NO        YES
    reset [commit]           REF     YES     NO        YES
    reset --hard [commit]    REF     YES     YES       NO
    checkout [commit]        HEAD    YES     YES       YES
    
    File Level
    reset (commit) [file]    NO      YES     NO        YES
    checkout (commit) [file] NO      YES     YES       NO

    “head”一列中的“REF”表示该命令移动了HEAD指向的分支引用,而“HEAD”则表示只移动了HEAD自身。 特别注意 “wd safe?” 一列,YES表示不会懂你在work dir的修改,NO代表会动你在work dir的修改。

  • 相关阅读:
    iconv 文件编码转换
    source insight 中文注释为乱码解决
    c: c代码书写规范
    Ubuntu: 搭建tftp,nfs服务器
    Linux: 信息查看
    liteos时间管理(九)
    最大连续子数列和
    递归为什么那么慢?递归的改进算法
    liteos信号量(八)
    liteos互斥锁(七)
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/15020513.html
Copyright © 2020-2023  润新知