【问题标题】:git - Easier way to do a simple one-commit squash?git - 做一个简单的一次性壁球的更简单方法?
【发布时间】:2014-06-19 15:44:19
【问题描述】:

我正在进行的项目要求所有功能贡献都是单个提交,但我仍然喜欢在此过程中提交我的进度,所以我通常在提交时压缩我的提交。

假设我正在分支上进行第一次新提交:

git commit -am "Added new feature"

从那时起,直到我提交我的更改,我都会这样做:

git commit -am "asdfasdasd"
git rebase -i HEAD~2

...然后在交互式 rebase 中压缩我的提交。

我每天这样做 10 到 20 次,对于我想要获得的看似简单的效果来说,这似乎是不成比例的大量按键。是否有更好/更快/更简单的方法来获得相同的结果?如果没有单一的魔法命令可以做到这一点,那么我想我正在寻找的是最有效的方法。从历史记录中弹出最近的提交(不丢弃其中包含的更改!),然后再次提交,这将包括来自弹出提交的更改以及工作更改。

【问题讨论】:

  • 项目是否使用了功能分支?还是每个人都在 master 中工作,只有在完成后才推动?
  • @schwern 我们使用功能分支。

标签: git commit rebase squash


【解决方案1】:

有没有更好/更快/更简单的方法来获得相同的结果?

我不确定是否有更快/更好/更简单的方法来做壁球,但我很确定解决这个问题的另一个很好的解决方案是:

  • V1 使用来自git merge--squash 标志。
  • V2 软重置和提交
  • V3 编写别名或脚本来为您完成工作

V1.

首先,您必须重置最后 X 次提交 (git reset --hard HEAD~3),然后应用 git merge --squash HEAD@{1},因为 HEAD@{1} 是上一个命令之前分支所在的位置。

V2

您可以查看 V2,可能您会发现它更简洁:git reset --soft HEAD~3 && git commit 但我个人不喜欢它。

V3

当然,您可以编写一个别名来自动化整个过程。可能你会发现这很有用:

  1. 最好的!:https://coderwall.com/p/-p2gla
  2. https://github.com/mozilla/pdf.js/wiki/Squashing-Commits
  3. http://inputvalidation.blogspot.ro/2010/12/automatic-squashing-of-last-git-commits.html

【讨论】:

    【解决方案2】:

    使用git commit --amend -am "message goes here"(或--amend -a——通常以前的提交消息是一个很好的起点——或者甚至在手动添加之后只使用--amend等)。 --amend 获取此 git 提交历史记录:

    ...-o-X-Y   <-- branch
    

    实际上执行“软重置”以使标签branch 指向X,以便新提交的父级再次成为X,从而产生此提交历史记录:

            Y   [no label, but still in reflog as branch@{1}]
           /
    ...-o-X-Z   <-- branch
    

    当你执行你的 commit-and-rebase 时,首先:

    ...-o-X-Y-Z   <-- branch
    

    (新的提交),然后:

            Y-Z   [no label, but still in reflog as usual]
           /
    ...-o-X-Z'    <-- branch
    

    其中Z'YZ 的squash-commit。所以这些是不同的,但就您的目的而言,可能同样有用。

    【讨论】:

    • 直到现在我还以为git commit --amend -am 只是为了修改提交信息。这正是我想要的,谢谢!
    【解决方案3】:

    将功能工作压缩到单个提交中的价值值得怀疑。一些不必要的流失是有用的。您会丢失有关每次更改的原因的重要信息,并最终得到一个可能很大且难以查看的 blob。版本控制的部分目的是让五年后有人可以回答“为什么这条线在这里”的问题,而挤压会丢失这些信息。如果人们不喜欢查看大量更改,他们可以使用git diff feature master 获得壁球效果,而不会丢失未来的信息。但你可能无法控制。

    要缓解此问题,请采取简单的权宜之计,即在分支中处理您的功能。这是你应该经常做的事情,以避免弄乱主人并将部分完成的工作推给其他人。正常工作,正常提交。当你的功能完成后,合并时才挤压。

    • git checkout -b 功能/随便
    • ...正常工作和提交...
    • git checkout master
    • git merge --squash 功能/其他
    • git 提交

    这样,您在工作时就可以享受功能分支的所有好处,并且仍然可以遵循 squash 政策。

    【讨论】:

    • 不是对所问问题的直接回答,但肯定是处理一般问题的更好方法,所以我赞成:-)
    • @torek 谢谢。这个问题已经有很多很好的答案了。有时问题不在于答案,而在于揭示真正的问题。 “如何用螺丝刀更有效地将钉子钉入木头?” “这是一把锤子。” “这不是我问的!......什么是锤子?”
    猜你喜欢
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-03
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多