【问题标题】:Difference between git reset and git cherry-pickgit reset 和 git cherry-pick 的区别
【发布时间】:2017-01-12 07:54:50
【问题描述】:

我从https://github.com/blog/2019-how-to-undo-almost-anything-with-git 读到这个:

如果您想恢复项目的历史记录,请使用 git reset --hard 如果您想将其中一个提交准确地重放到您的存储库中,请使用 git cherry-pick 。

我是初学者,还没有进入分支。对我来说,cherry-pick 的用法似乎与 git reset 相同。我想知道 git cherry-pick 实际上与 git reset 有什么不同,因为我只在一个分支中工作。

【问题讨论】:

    标签: git github git-cherry-pick


    【解决方案1】:

    Cherry-picking 用于合并属于另一个分支的特定(甚至是一系列)提交到当前签出 分支。

    git checkout foo
    #you are in branch foo. you make some EDITS on this branch.
    git commit -am "my changes to foo branch"
    git push 
    #The commit, say sha1, is pushed to foo branch.
    
    ### several other commits are pushed randomly by different users to this branch ###
    

    假设,另一个用户想要将此提交 sha1 从分支 foo 带到 same 存储库的分支 bar。请注意,在这种情况下,分支foo 可能会领先于sha1 提交状态的多个提交。

    foo : ORIG_HEAD -- sha1 -- sha2 -- sha3 -- .... shaN
                        ^~~~user want to cherry-pick 
                            only this commit
    

    tocherry-pick 提交 sha1 到分支 bar:

    git checkout bar
    git cherry-pick sha1 
    # The commit `sha1` is merged to your branch `bar` and is ahead by 1 commit
    

    Git reset 主要用于撤消本地提交或失败的 git pull/merge。它还用于清除 dirtly 工作树中的混乱。

    例如:

    $ git pull    
      Automatic merge failed; fix conflicts and then commit the result.
    $ git reset --hard   # clears the mess from the index file and the working tree.
    

    因此,cherry-picking 和 git-resetting 都会影响 HEAD 位置,但它们在用例方面有很大不同。

    【讨论】:

      【解决方案2】:

      git reset --hard 表示 git reset --hard HEAD 其中 HEAD 是对当前签出的提交或当前分支中的最后一个提交的引用(引用),即不要更改分支但要删除所有本地更改将删除所有暂存和未暂存的更改。 git reset 命令提供了很多选项,这里解释得很好:

      Can you explain what "git reset" does in plain english?

      而 Cherry Picking 意味着从一个分支中选择一个提交并将其应用到另一个分支上。如果你可以这样做。犯了一个错误并将更改提交到错误的分支,但不想合并整个分支。你可以只是例如。恢复提交并在另一个分支上挑选它。

      如果您推送到错误的分支,或者您的分支出现问题,由于系统上的旧 git 历史记录显示来自其他用户的大量提交(当多个用户工作时),您可以删除当前分支保持您的提交哈希安全,然后将提交挑选到将从 master 更新的新分支。 (这种情况有时会发生,当rebasemerge 无法解决问题时,可以选择cherry-pick

      引用自这个答案:

      来源: https://stackoverflow.com/a/30218784/4207394

      使用 git cherry-pick 命令 git cherry-pick commit 应用 由当前分支上的命名提交引入的更改。它会 引入一个新的、不同的提交。严格来说,使用 git cherry-pick 不会更改存储库中的现有历史记录; 相反,它增加了历史。与其他 Git 操作一样 通过应用差异的过程引入更改,您可能需要 解决冲突以完全应用来自给定提交的更改。 命令 git cherry-pick 通常用于引入特定的 从存储库中的一个分支提交到另一个分支。一种 常见用途是从维护中转发或反向端口提交 分支到开发分支。

      因此,当您想要重置提交或更改时,您可以使用git reset 和事件,如果您想要重置提交并保持该提交的更改安全,您可以使用git reset--soft 选项。如果你想从其他分支复制提交到其他分支,那么你可以使用git cherry-pickgit reset 有许多可用的选项,例如:

      重置为当前的HEAD

      git reset --hard HEAD
      

      重置一个提交并删除更改:

      git reset --hard HEAD~1
      

      this 1 可以是 n 以删除任意数量的提交。而且为了保留提交的更改,您可以使用--soft 而不是--hard

      cherry-pick 的语法是:

      git cherry-pick <commit-hash>
      

      【讨论】:

      • @Construct 我已经更新了我的声明,因为我理解你的担忧,但我并不清楚解释这个问题。当您有较旧的 git 历史并且很长时间没有更新它时,就会出现此问题。然后有时在您的功能分支中,它开始显示其他用户的提交,但文件中没有额外的更改。在这种情况下,您可以这样做。
      • @Construct:是的,他们会的。事实上,git rebase 只是一系列自动化的樱桃挑选操作,最后通过移动重新定位的分支指向最后一个这样的樱桃挑选提交。
      • @Deep: git cherry-pick 表示“复制一个提交”。您选择提交,无论您现在身在何处,它都会作为新提交添加。 (您可以复制多个,但默认只有一个。)另一方面,git rebase 表示:“复制 尽可能多的提交来自当前分支,我现在所在的位置,to 我告诉你移动到的位置;然后将我的当前分支移动到 last 复制的提交。”最后一步——移动分支——有效地删除来自该分支的原始(现在复制的)提交。 (这很好,因为它们是复制的。)所以它们非常不同。
      • @Deep:如果您使用git rebase -i,“根据需要复制尽可能多的提交”部分字面意思是使用樱桃挑选(它可能会使用另一种机制来实现非-交互式变基)。这就是为什么你会得到一个带有一堆“pick”命令的编辑器:这些是要被精心挑选的提交。但是,“删除”步骤是新的——所有复制的主要目的是使新的 副本 出现在提交图中的不同点。你可能想看看,例如,stackoverflow.com/q/39154794/1256452 这里。
      • 好吧,这深入杂草,因为正如我所提到的,rebase 可能实际上运行git cherry-pick,或者它可能运行git format-patch ... | git am ...。在需要合并的情况下,两者都会尝试做同样的事情,但樱桃挑选形式更适合重命名的情况。这就是为什么现代git rebase-m 标志参数,强制它使用git cherry-pick 而不是git format-patch。但总的来说,是的:如果只有一个提交要复制,您可以使用三个 Git 命令 git checkout; git cherry-pick; git branch -f 而不是 1 个 git rebase
      猜你喜欢
      • 2012-10-16
      • 2011-07-06
      • 1970-01-01
      • 2013-11-18
      • 1970-01-01
      • 1970-01-01
      • 2015-08-26
      • 1970-01-01
      • 2012-06-24
      相关资源
      最近更新 更多