理解'git reset--很难`

理解'git reset--很难`,git,Git,假设我有一个Git回购协议,按照以下顺序向主机提交:a、B、C、D。我想将主机回滚到提交a后的状态;换句话说,放弃B、C和D中的更改。我很确定,git reset--hard可以做到这一点。但是,我想有选择地重新应用一些被丢弃的补丁(git cherry pick就是我想要的,对吗?),所以我的具体问题是: git reset--hard是否从提交历史记录中删除任何内容?如果我将主数据重置为A,B、C和D是否仍会在回购协议中徘徊 git cherry pick是否允许我执行上述操作,还是我误解了

假设我有一个Git回购协议,按照以下顺序向主机提交:a、B、C、D。我想将主机回滚到提交a后的状态;换句话说,放弃B、C和D中的更改。我很确定,
git reset--hard
可以做到这一点。但是,我想有选择地重新应用一些被丢弃的补丁(
git cherry pick
就是我想要的,对吗?),所以我的具体问题是:

  • git reset--hard是否从提交历史记录中删除任何内容?如果我将主数据重置为A,B、C和D是否仍会在回购协议中徘徊

  • git cherry pick
    是否允许我执行上述操作,还是我误解了


  • 要正确理解git reset,您需要所有这些信息:

    • 从某种意义上说,提交本身存在于任何分支名称之外

      当您进行提交时,Git会为其分配一个唯一的散列ID。您进行的新提交会在其中存储您进行提交时当前提交的任何提交的散列ID。我们可以使用这些哈希ID将提交链接在一起:

      A <-B <-C <-D
      
      现在Git知道
      D
      正在使用中。由于
      D
      指向
      C
      ,Git知道
      C
      正在使用,依此类推

    • 特殊名称
      HEAD
      通常包含分支的名称。分支名称本身,例如
      master
      ,通常具有标识某些特定提交(
      D
      )的作用,从而保持
      D
      处于活动状态。名称
      HEAD
      用于告诉Git哪个分支名称将被视为当前分支

    • 使用
      git commit
      进行新提交时,git使用索引的内容进行新提交。索引,也称为暂存区,有时也称为缓存,位于当前(头)提交和工作树之间。因此,当前提交的每个文件都有(最多)三个版本:头文件中的版本、索引中的版本和工作树中的版本

      您可以在索引和工作树之间来回复制文件,并且可以将任何提交中的文件复制到索引中;但是提交是只读的,因此不能从索引复制到现有提交中。您只能从索引进行新的提交

    • 当然,工作树以正常的可读写方式保存文件,而不是某些特殊的Gitty格式(如提交本身和索引中使用的格式)

    git reset
    所做的(在正常模式下,
    --soft
    --mixed
    ,和
    --hard
    )最多可以执行三项工作:

  • 通过
    HEAD
    更改某些内容(通常是当前分支存储的哈希ID)。它总是这样做,但是如果使用
    HEAD
    作为新值,新值与旧值相同,因此实际上没有任何变化。(如果
    --soft
    ,请在此停止)
  • 重新设置索引。此部分是可选的:它仅适用于
    --混合
    --硬
    。(如果
    --mixed
    ,则停止此处)重置意味着将所有内容从(现在重新设置)
    头复制到索引中
  • 重新设置工作树。此部分是可选的:它仅适用于
    --hard
    。重置意味着将所有内容从(现在已重新设置)索引复制到工作树中
  • 现在,您提到要将内容回滚到提交
    A
    期间的状态。正确定义事物是这里的问题。我们可以使分支名称指向commit
    A

    A   <-- master (HEAD)
     \
      B--C--D
    
    您现在可以运行
    git cherry pick
    git cherry pick save~1
    (这两个选项都将标识commit
    C
    )。Git然后将commit
    C
    的内容与commit
    B
    的内容进行比较。无论更改了什么,Git现在都会尝试对索引和工作树的内容进行更改。如果所有这些都成功,Git将提交结果:

    A--C'   <-- master (HEAD)
     \
      B--C--D   <-- save
    

    A--C'要正确理解
    git reset
    您需要所有这些信息:

    • 从某种意义上说,提交本身存在于任何分支名称之外

      当您进行提交时,Git会为其分配一个唯一的散列ID。您进行的新提交会在其中存储您进行提交时当前提交的任何提交的散列ID。我们可以使用这些哈希ID将提交链接在一起:

      A <-B <-C <-D
      
      现在Git知道
      D
      正在使用中。由于
      D
      指向
      C
      ,Git知道
      C
      正在使用,依此类推

    • 特殊名称
      HEAD
      通常包含分支的名称。分支名称本身,例如
      master
      ,通常具有标识某些特定提交(
      D
      )的作用,从而保持
      D
      处于活动状态。名称
      HEAD
      用于告诉Git哪个分支名称将被视为当前分支

    • 使用
      git commit
      进行新提交时,git使用索引的内容进行新提交。索引,也称为暂存区,有时也称为缓存,位于当前(头)提交和工作树之间。因此,当前提交的每个文件都有(最多)三个版本:头文件中的版本、索引中的版本和工作树中的版本

      您可以在索引和工作树之间来回复制文件,并且可以将任何提交中的文件复制到索引中;但是提交是只读的,因此不能从索引复制到现有提交中。您只能从索引进行新的提交

    • 当然,工作树以正常的可读写方式保存文件,而不是某些特殊的Gitty格式(如提交本身和索引中使用的格式)

    git重置的功能(在正常模式下,A--C' <-- master (HEAD) \ B--C--D <-- save