如何从 git 历史记录中清除多余的合并?

How to clean superfluous merges from the git history?

我有一个同事试图通过编辑和提交来调试 Azure DevOps 管道,例如azure-pipelines-1.ymlrequirements.txtmaster 分支,导致一系列提交和相关合并。请参阅生成的 git 历史片段作为此问题的结尾。

清理生成的 git 历史并消除所有 azure-pipelines-1.ymlrequirements.txt 提交以使其看起来有点像这样的策略是可行的:

* | f1827ab Disabled root logger
* | 4941773 SNOW API and AD validator
* | 6ba3ce7 Handler unit tests
* | 76af104 slate3k for handling PDF and openpyxl for handling Excel
* | 6002e95 Jira "diff" scan, Jira project scan, Stash project scan
* | 11d4a2a Explicit column names for ORM models
* | a5524e1 Updated Dockerfile, pip.conf, and requirements.txt
* | f536cef Refactored packages for unittest. Created unit tests for handlers

?

特别是,我不能使用 git rebase -i,因为它无法处理合并?

git log:

*   9e4028d (HEAD -> master, appsec/master) Merge branch 'master' of https://azuredevops.danskenet.net/Main/Application%20Security/_git/sds
|\
| * 5b4b06d Updated requirements.txt
| * e6be15d Added file Pipfile
| * 7cbae95 Updated requirements.txt
| * 6416de8 Updated azure-pipelines-1.yml
| * 4bea01c Updated azure-pipelines-1.yml
| * 995410c Update azure-pipelines-1.yml for Azure Pipelines
| * 2c708e1 Update azure-pipelines-1.yml for Azure Pipelines
| * 3c2fa59 Update azure-pipelines-1.yml for Azure Pipelines
| * f712143 Updated requirements.txt
| * 529b0cc Updated requirements.txt
| * d84d97c Update azure-pipelines-1.yml for Azure Pipelines
| * d2e8ca7 Update azure-pipelines-1.yml for Azure Pipelines
| * b2ddfb1 Update azure-pipelines-1.yml for Azure Pipelines
| * 4793fd0 Update azure-pipelines-1.yml for Azure Pipelines
| * de8cb72 Update azure-pipelines-1.yml for Azure Pipelines
| * 6571ef6 Update azure-pipelines-1.yml for Azure Pipelines
| * a5cde18 Update azure-pipelines-1.yml for Azure Pipelines
| * fe93475 Update azure-pipelines-1.yml for Azure Pipelines
| * f4d6413 Updated requirements.txt
| * dcdd00f Updated requirements.txt
| * b69410f Updated blackduck.yml
| * 876a93b Updated requirements.txt
| * b6a5016 Updated blackduck.yml
| * 8a3fdd7 Updated requirements.txt
* | f1827ab Disabled root logger
* | 4941773 SNOW API and AD validator
* | 6ba3ce7 Handler unit tests
* | 76af104 slate3k for handling PDF and openpyxl for handling Excel
* | 6002e95 Jira "diff" scan, Jira project scan, Stash project scan
* | 11d4a2a  Explicit column names for ORM models
* | a5524e1 Updated Dockerfile, pip.conf, and requirements.txt
* | f536cef Refactored packages for unittest. Created unit tests for handlers
|/
*   536d2c2 Merge remote-tracking branch 'appsec/master' into master
|\
| * 465a25e Update azure-pipelines-1.yml for Azure Pipelines
| * 8ac226b Update azure-pipelines-1.yml for Azure Pipelines
| * c22a1be Update azure-pipelines-1.yml for Azure Pipelines
...

我不确定我能 100% 满足您的需求,但我认为您正在寻找git rebase -i:您可能想要重播在 :

之上的“侧枝”
* f1827ab Disabled root logger

这是一种方法:

# from master :
git checkout -b wip 5b4b06d
git rebase -i f1827ab

交互式变基会让你有机会删除所有你想排除的提交;您也可以将多个提交组合在一起(squashfixup)。

完成此临时 wip 分支的工作后,您可以将 master 设置为该特定提交:

git checkout master
git reset --hard wip

关于 git reset --hard 的一般警告:

git reset --hard 是为数不多的破坏性 git 命令之一,它可以从您的磁盘中删除未提交的修改,而没有任何方法可以恢复它们。

只有当你的工作树是干净的,或者你知道你可以丢弃磁盘上的所有更改时才使用它。