【问题标题】:How to split git commit in this specific way如何以这种特定方式拆分 git commit
【发布时间】:2019-07-24 09:23:28
【问题描述】:

情况:我有一个 git 提交(在 HEAD),其中混合了额外的日志记录代码,然后是一些“真实代码”。

现在我想做以下事情:

  1. 编辑出所有的日志代码,基本清理代码库
  2. 提交这个
    • 我现在在最后两次提交中获得了所需的状态,但它们的顺序错误,首先添加所有内容,然后删除日志记录,当我想要添加其他代码然后添加日志记录时
  3. 交换这两个提交,这样
    • 首先添加实际功能没有日志记录
    • 然后将日志记录代码添加到自己的提交中

现在我可以“手动”执行此操作,方法是获取包含日志记录的代码的纯副本,然后按照上面的描述删除日志记录并将这些提交压缩为一个(因此提交历史记录中根本没有日志记录代码),然后恢复包含日志记录的代码副本,并将其添加为新提交。

但是有没有办法使用 git 功能优雅地做到这一点并且减少人为错误的可能性?

为了澄清,我不想选择在我想要的第一次提交中包含哪些部分(因为那里有很多小的更改,我不想再次查看它们)。我想从第一次提交中选择要删除的部分,然后添加为新的第二次提交。

【问题讨论】:

标签: git


【解决方案1】:

我认为没有任何方法可以做到没有任何人为错误的可能性,但是通过使用一些 git 功能并基本上撤消你的提交,然后只在每次提交中添加你想要的部分,你可以实现什么你描述的。

我会通过软重置为HEAD~1 来做到这一点,然后使用git add --patch 在第一次提交中只添加您想要提交的部分,提交,然后添加日志记录。

以下是我的处理方法:

  1. git reset --mixed HEAD~1 这会重置您的最后一条提交消息并取消暂存这些更改。
  2. git add --patch 这为您提供了一种交互模式,您可以在其中选择要暂存的未暂存更改的哪些部分。如果代码块太大(即您只想提交其中的一部分),您可以通过点击s 将其拆分为较小的部分,然后只暂存较小的部分。它支持将代码大块拆分为单行更改,因此希望这对您来说已经足够了。
  3. git commit 提交你的“真实代码”
  4. git add . 暂存其余更改(日志记录代码)
  5. git commit 再次提交日志代码

通过使用这种方法,您不必在任何地方复制粘贴任何代码,从而至少减少了人为错误的机会。

【讨论】:

  • 提示:git reset --soft HEAD~1; git reset HEAD . 可以替换为git reset --mixed HEAD~1
  • 谢谢! Git 确实有很多隐藏的宝石,有时需要一段时间才能找到。
  • 我想特别避免一一添加更改。我只想搜索所有日志记录语句并删除它们(从第一次提交中),而不查看其中的所有其他内容(如果我想以另一种方式进行,我必须这样做)。
  • 啊。我不认为有 git 功能可以做到这一点,但我认为一些带有 grep、sed 和补丁的 shell 脚本应该能够实现这一点
【解决方案2】:

这是成功复制您的要求的例程。

假设您有以下历史记录。

ef5e245  Remove logging 
9fffc54  Add real code and logging
bdf6bce  Add initial commit

在临时分行结账。

git checkout -b temp 

返回主分支并在更改之前重置为提交。

git reset --hard bdf6bce

然后执行以下操作(-e 允许您在挑选樱桃时编辑提交消息)。

git cherry-pick ef5e245 -X theirs -e # Add real code
git cherry-pick 9fffc54 -X theirs -e # Add logging

最终,您将拥有以下提交的新历史。

3c8ce38  Add logging
6afa0ab  Add real code
bdf6bce  Add initial commit

除非您创建了新文件,否则您不应该遇到任何合并问题。

【讨论】:

  • 在接受/投票之前,您是否对此进行了测试?我的意思是,这可能是一个有点无厘头的问题,但是第一个樱桃选择真的做到了预期,结合提交(而不是试图删除尚未添加的行)?
【解决方案3】:

好的,我解决了(警告:我没有测试这个确切的命令序列,因为有一些试验和错误,所以如果你使用它,请不要脱离你自己的大脑):

git checkout branch_to_split_the_head
git tag desired_result # also backup, if you haven't pushed
# edit the source to the state for 1st commit, test etc
git add -u
git status # make sure status looks ok
git diff --staged # make sure removed lines etc look ok
git commit --amend --no-edit # create correct 1st commit
git merge -X theirs desired_result # ...add correct 2nd commit
git diff desired_result # there shouldn't be differences
# git push -f # as usual -f needed after rewriting history

每个更改都将是合并冲突,但合并策略选项-X theirs 应确保它们自动解析为所需的最终结果版本。

【讨论】:

    【解决方案4】:

    您可以重置到上次提交之前,保持工作树完好无损:

    git reset HEAD^
    

    您现在应该将所有更改都置于未提交和未暂存状态。您可以使用git add -p 以交互方式在第一次提交(即日志记录)中添加您想要的更改,然后提交。

    现在您应该只剩下可以单独提交的“真实代码”更改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-04
      • 2015-08-08
      • 2015-10-02
      相关资源
      最近更新 更多