git reset的实际用法--soft? [英] Practical uses of git reset --soft?

查看:375
本文介绍了git reset的实际用法--soft?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用git超过一个月。事实上,我昨天才第一次使用重置,但软重置对我来说依然没有什么意义。



据我所知,我可以使用软重置编辑提交而不改变索引或工作目录,就像我对 git commit --amend 所做的那样。

这两个命令是否真的相同( reset --soft vs commit - 修改)?有任何理由在实际中使用这两者之一?更重要的是,除了修改提交外,是否还有其他用于 reset --soft 的其他用途?

解决方案> git reset 全部关于移动 HEAD

问题:工作树和索引怎么样?

当使用 - soft 时,移动 HEAD ,只有 HEAD

这与 commit --amend 为:




  • 它不会创建新的提交。
  • 它可以实际上将HEAD移动到任何提交(如 commit --amend 只是关于 not 移动HEAD,而允许重做当前提交)
  • >





刚刚发现这个结合的例子:


  • 经典合并

  • 子树合并



  • 全部合为一体(章鱼,因为有两个以上的分支合并)提交合并。



    TomaswereHamsterCarnecky 在他的



    • merge.htmlrel =noreferrer>Subtree Octopus合并如果要将一个项目合并到另一个项目的子目录中,并且随后保持该子项目处于最新状态,则可以使用子树合并策略。它是git子模块的替代品。

    • 章鱼合并策略可用于合并三个或更多分支。正常的策略可以合并只有两个分支,如果你尝试合并更多,git自动回落到章鱼策略。



    问题是您只能选择一种策略。但我想将这两者结合起来,以获得一个清晰的历史记录,其中整个存储库已原子更新为新版本。



    我有一个超级项目,我们称之为 projectA 和一个子项目 projectB ,我将它们合并到 projectA

    (这是子树合并部分)


    我还维护了一些本地提交。

    ProjectA 定期更新, projectB 每几天或几周都会有一个新版本,通常取决于特定版本的 projectA



    当我决定更新这两个项目时,我不会简单地从 projectA projectB ,因为它会为整个项目的原子更新创建两个提交

    相反,我创建了一个合并提交,它包含了 projectA projectB 和我的本地提交

    棘手的部分是这是一个章鱼合并(三头),但是 projectB 需要与子树策略合并。所以这是我做的:



     #用默认策略合并projectA:
    git合并projectA / master

    #将子项策略合并到projectB:
    git merge -s subtree projectB / master

    在这里,作者使用了一个 reset --hard ,然后 read-tree 来恢复前两次合并对工作树和索引所做的操作,但这正是 reset --soft 可以帮助您:

    如何重做这两个合并,哪些工作,即我的工作树和索引是好的,但不必记录这两个提交?

     #移动HEAD,只有HEAD,两个提交! 
    git reset --soft HEAD @ {2}

    现在,我们可以恢复Tomas的解决方案:

     #假设我们做了一个带有三个头的章鱼合并:
    echo $(git rev-parse projectA / master)> .git / MERGE_HEAD
    echo $(git rev-parse projectB / master)>> .git / MERGE_HEAD

    #最后执行commit:
    git commit






    所以,每一次:


    • 你对最终结果感到满意(根据工作树和索引)

    • 您不满意所有提交到达目标的提交:


    git reset --soft 就是答案。


    I have been working with git for just over a month. Indeed I have used reset for the first time only yesterday, but the soft reset still doesn't make much sense to me.

    I understand I can use the soft reset to edit a commit without altering the index or the working directory, as I would with git commit --amend.

    Are these two commands really the same (reset --soft vs commit --amend)? Any reason to use one or the other in practical terms? And more importantly, are there any other uses for reset --soft apart from amending a commit?

    解决方案

    git reset is all about moving HEAD.
    Question: what about the working tree and index?
    When employed with --soft, moves HEAD, and only the HEAD.
    This differ from commit --amend as:

    • it doesn't create a new commit.
    • it can actually move HEAD to any commit (as commit --amend is only about not moving HEAD, while allowing to redo the current commit)

    Just found this example of combining:

    • a classic merge
    • a subtree merge

    all into one (octopus, since there is more than two branches merged) commit merge.

    Tomas "wereHamster" Carnecky explains in his "Subtree Octopus merge" article:

    • The subtree merge strategy can be used if you want to merge one project into a subdirectory of another project, and the subsequently keep the subproject up to date. It is an alternative to git submodules.
    • The octopus merge strategy can be used to merge three or more branches. The normal strategy can merge only two branches and if you try to merge more than that, git automatically falls back to the octopus strategy.

    The problem is that you can choose only one strategy. But I wanted to combine the two in order to get a clean history in which the whole repository is atomically updated to a new version.

    I have a superproject, let's call it projectA, and a subproject, projectB, that I merged into a subdirectory of projectA.

    (that's the subtree merge part)

    I'm also maintaining a few local commits.
    ProjectA is regularly updated, projectB has a new version every couple days or weeks and usually depends on a particular version of projectA.

    When I decide to update both projects, I don't simply pull from projectA and projectB as that would create two commits for what should be an atomic update of the whole project.
    Instead, I create a single merge commit which combines projectA, projectB and my local commits.
    The tricky part here is that this is an octopus merge (three heads), but projectB needs to be merged with the subtree strategy. So this is what I do:

    # Merge projectA with the default strategy:
    git merge projectA/master
    
    # Merge projectB with the subtree strategy:
    git merge -s subtree projectB/master
    

    Here the author used a reset --hard, and then read-tree to restore what the first two merges had done to the working tree and index, but that is where reset --soft can help:
    How to I redo those two merges, which have worked, i.e. my working tree and index are fine, but without having to record those two commits?

    # Move the HEAD, and just the HEAD, two commits back!
    git reset --soft HEAD@{2}
    

    Now, we can resume Tomas's solution:

    # Pretend that we just did an octopus merge with three heads:
    echo $(git rev-parse projectA/master) > .git/MERGE_HEAD
    echo $(git rev-parse projectB/master) >> .git/MERGE_HEAD
    
    # And finally do the commit:
    git commit
    


    So, each time:

    • you are satisfied with what you end up with (in term of working tree and index)
    • you are not satisfied with all the commits that took you to get there:

    git reset --soft is the answer.

    这篇关于git reset的实际用法--soft?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆