【笔记】Git|将git仓库中所有的 commit 合成一个,清空所有 git 提交记录

这篇具有很好参考价值的文章主要介绍了【笔记】Git|将git仓库中所有的 commit 合成一个,清空所有 git 提交记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在对代码进行开源时,我们往往并不希望代码开发过程中的提交记录被其他人看到,因为提交的过程中往往会涵盖一些敏感信息。因此会存在 将仓库中所有 commit 合成一个 的需求。

直觉上,往往会用 rebase 和 squash 或 reset,不过我尝试了一下存在问题,会出现最后仍然剩两个 commit 的情况。

接下来分享三种可用的方式,并简单介绍一下为什么不用 rebase

方式一:git commit --amend(官方建议)

这一种方式意思就是追加提交,最符合 git 的使用原则,也最轻量。我建议使用这种方式,这也是 git 官方建议的方式。

首先在 github 网页上或者使用 git log 查看第一个 commit 的 id,然后运行:

git reset --soft <第一个 commit 的 id>
git commit --amend

这两行指令的含义是:

  1. 将当前分支的状态切换到第一个提交中,并保留本地的修改以及暂存区的设置;
  2. 将现在的暂存区的内容直接 amend 到前一个提交(在这里指的就是第一个 commit)。

运行这两行指令之后,将会弹出一个新的编辑框,要求填写 commit message。默认的 commit message 就是你的第一个提交的 commit 信息,如果你需要修改,就修改一下。

git 合并提交记录,科普,笔记,# 琐碎小记录,git,github

更多配置

  1. 如果不希望保留第一个 commit 的作者信息,可以加参数--reset-author

    git commit --amend --reset-author
    
  2. 如果希望不要修改作者和日期,可以加参数--no-edit

    git commit --amend --no-edit
    
  3. 如果希望修改日期,可以加参数--date,例如:

    git commit --amend --date "Mon Aug 1 12:23:11 2022 +0800"
    

以上配置均可以组合使用。

方式二:新建本地的 git 仓库

这种方式是最直观直接的,新建了当然什么都没有了咯。
不过操作起来比较麻烦,需要删除文件夹、调整当前的目录。

# 1. 删除当前目录的 .git/ 文件夹
# 2. 新建 git 仓库
git init
# 3. 建立当前 git 目录与远端仓库的关系
git remote add origin git@github.com:user/repo
# 4. 重新添加所有文件并提交
git add .
git commit -m 'message'
# 5. 对远端仓库强制更新
git push -f origin master

方式三:新建空白的子分支

这种方式也很直观,就是新建空白子分支,再将子分支直接命名为原来的主分支,李代桃僵。
不过在推送时有点邪门,弄不好也容易出错,不建议使用,不过可以用来了解一下 orphan 参数。

# 1. 新建一个空白分支
git checkout --orphan <分支名> # orphan 代表这个分支是一个初始提交
# 2. 重新添加所有文件并提交
git add .
git commit -m "new"
# 3. 删除原来的主分支
git branch -D master
# 4. 将新建的空白分支的名称改成master
git branch -m master
# 5. 对远端仓库强制更新
git push -f origin master --set-upstream

注意,主分支有可能叫做 main,也有可能叫做 master

为什么不建议用 rebase 进行该合并操作?

rebase 用于压缩 commit 的时候,往往是这样的过程:

  1. git rebase -i HEAD~n,其中 n 是需要合并的 commit 数量;
  2. 弹出新的编辑窗口,选择(pick)一个分支,压缩(squash)其他分支:
    pick commitid
    s commitid1
    s commitid2
    
  3. 保存并退出。

rebase 这个 git 指令仅看名字,意思大概是重新设置一下 base commit。因此它在使用时,是需要有一个 base commit 的,它的 pick、squash 等操作,都是基于这个 base 去做的。

就拿上述所说的过程中的第二步解释,在这一步中,其 base commit 其实是 commitidparent commit,它实际上做的操作,是先切换到 parent commit,然后再在 parent commit 里去进行 cherry-picksquash 操作。然后再重新提交。

而你无法使用 rebase 去合并仓库中的所有 commit 的原因,也仅仅是因为它的机制:

  1. 最初的那个 commit,它没有它的 base commit。所以你无法使用 rebase 去 pick 第一个 commit。
  2. 当你每个 commit 都不 pick 的时候,压缩完了的 commit 将会不知道存给哪个 commit。

所以如果要使用 rebase 里提供的 squash(压缩)对所有分支进行压缩,压缩成唯一的一个 commit,那 rebase 操作时,要么无法找到 base commit 从而指令直接运行出错,要么你压缩完成之后 commit 不知道存给谁就报错。

而这些报错在处理起来,对于一个只想简单交个代码的人来说是比较难懂的。

如果你不相信,我这边提供一个例子。

假如现在总共有 3 个 commit,其中第一个 commit 的 id 是 d2d48778,如下所示:

git 合并提交记录,科普,笔记,# 琐碎小记录,git,github

用 rebase 进行合并的时候,只能对最后两个 commit 进行操作。
如果你强行操作 3 个,运行的是如下指令:

git rebase -i HEAD~3

那你将会得到报错的结果fatal: invalid upstream 'HEAD~3'

git 合并提交记录,科普,笔记,# 琐碎小记录,git,github

如果你运行 git rebase -i HEAD~2,那么将一切正常。

而如果你发觉不对劲,因此干脆直接去 rebase 第一个 commit,运行了如下指令:

git rebase -i d2d48778

那你将不会得到报错,但会得到如下编辑框,没有第一个 commit 的 id:

git 合并提交记录,科普,笔记,# 琐碎小记录,git,github

此时,直观上讲,我们肯定会不管不顾地将 pick 直接全改成 squash,期望出现奇迹。可是当我们保存并退出时,会发现出现的是报错error: cannot 'squash' without a previous commit,要求必须选择一个此前的 commit 去作为压缩的结果存储的 commit:

git 合并提交记录,科普,笔记,# 琐碎小记录,git,github

既然如此,干脆手动新增一行 pick 行不行呢?强行指定第一个 commit 作为存储 squash 结果的 commit,如下所示:

git 合并提交记录,科普,笔记,# 琐碎小记录,git,github

实际上,这也不行。原因就在于第一个 commit 没有前一个 commit,根本不能被 cherry-pick。如果你真的这样做了,那么你会得到一个报错The previous cherry-pick is now empty, possibly due to conflict resolution.,与我的描述一致,如下图所示:

git 合并提交记录,科普,笔记,# 琐碎小记录,git,github

你或许还注意到了 git 官方给出了一个解决办法,就是 git commit --allow-empty,那么,它解决的结果是什么呢?当运行了这行指令之后,弹出新的编辑框要求输入 commit message,然后查看当前 git 日志,如下两图所示:

git 合并提交记录,科普,笔记,# 琐碎小记录,git,github
git 合并提交记录,科普,笔记,# 琐碎小记录,git,github

你会惊讶地发现,居然还是有两个提交。

更可怕的是,当你终于想起来去看看自己的 git 状态时,你会发现操作日志也没有了,rebase 也没执行,本地的修改也不见了。如下图所示:

git 合并提交记录,科普,笔记,# 琐碎小记录,git,github

虽然实际上,本地的修改其实还在 本地的 commit 文件里,但由于你也不知道到底怎么 rebase,在百般 rebase 失败之后,你或许已经忘记了最新代码的 commitid、或者已经失手推送更新了远端仓库、或者已经忘记了自己到底要改什么东西,最后的结果可能是让人崩溃的。

其实在 git status 时,git 命令行就已经显示了这个问题的所有解决方案:

  1. 你可以修改你的 rebase 操作,使用 git rebase --edit-todo,让它 pick 第二个 commit、基于第一个 commit,这样起码能够保留你的代码文件,只是第一个 commit 会多余。
  2. 你可以使用git commit --amend操作,只是做简单的追加操作,而不是像现在这样使用 rebase 乱来。具体可以参考本文的方式一
  3. 你可以重新执行 rebase 操作,使用 git rebase --continue,如果你坚持觉得自己是正确的话。(当然,这样做只会导致继续报错罢了)

综上所述,我为了讲清楚为什么不在合并所有 commit 的时候使用 rebase,简单地思考并描述了一下 rebase 的原理和机制,希望对遇到这个问题的人有所帮助。

另外,大部分机制是直接通过操作看或猜出来的,仅结合 git 输出信息,并未结合官方的描述文档,若有错误,还请在评论区留言指正。

本账号所有文章均为原创,欢迎转载,请注明文章出处:https://blog.csdn.net/qq_46106285/article/details/130459829。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。文章来源地址https://www.toymoban.com/news/detail-672442.html

到了这里,关于【笔记】Git|将git仓库中所有的 commit 合成一个,清空所有 git 提交记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • git快速查看某个文件修改的所有commit

    1. git blame file git blame 可以显示历史修改的每一行记录,有时候我们只想了解某个文件一共提交几次commit,只显示commit列表,这种方式显然不满足要求。 2.git log常规使用 (1)显示整个project的所有commit     (2)显示某个文件的所有commit 这是git log不添加参数的常规使用,可查

    2024年02月09日
    浏览(34)
  • 【Git 操作指南】| 撤销远程仓库的 push 以及 git commit 提交

    执行 git log 查看版本日志,找到目标版本。 执行 git reset --soft version numbere ,如 git reset --soft d8cedc98e008e14a35d3faf424764648fb29d55b ,重置为之前提交的版本,接着执行 git log 查看是否已经退回到之前的版本。 (注意, git reset --soft 只改变了 HEAD 的指向位置,本地代码不会发生改变

    2024年02月16日
    浏览(45)
  • Git---本地仓库有多条commit,如何push某一条commit到远端

    举例如下: 第一种方式, 即符合git操作的规则,从最初的commit开始一个一个提交,但是不能实现指定某一个commit,基本满足日常的开发异常情况了 (只能按顺序提交) 图一 本地commit了3次提交但是并不想一下push到远程,根据功能或者时间的原因,想一个一个提交  此时可以

    2024年02月02日
    浏览(32)
  • 【经验】Git|如何删除错误的commit?(存在大文件无法push的commit、不需要的commit等情况、清除所有commit的情况)

    如果你在本地多次提交了commit,但是其中有一个commit交错了、或者无法推送, 就像下面这张图这样: 你可以安装以下步骤操作。 通过 git log 想清楚自己需要切换到哪一个commit状态,查看commit id: 将仓库的状态恢复到 能够正常提交的状态/需要删除的状态的上一个commit状态

    2024年02月03日
    浏览(51)
  • git将所有patch导出来,并且将其命名为提交的commit记录

    git基本是大部分码农都会用的工具,我们公司以前在维护系统源码的时候,用的repo的管理方式,后来觉得这种方式不太方便,于是,后来都是使用一个大的git仓库进行源码管理。源码仓库跟应用仓库最大的区别在于它非常的庞大,对于我们开发者来说,其实最重要的并非源码

    2024年02月01日
    浏览(32)
  • git:使用git rebase合并多次commit为一个

    git log:找到需要合并的最早 commit 的父级 git rebase -i 73a5cd8597 除第一个 pick 外,将其它改成 s,改完后保存退出 保存完后弹出 commit message 合并提示,根据这次合并的目的,重写commit message,改完后保存 修改为: 做完上述操作后,自动合并多个 commit 合并成为一个并提交,并生

    2024年01月25日
    浏览(36)
  • 命令行--git--多次commit如何合并成一个commit

    参考:https://blog.csdn.net/qq_50652600/article/details/120800309 在我们平时开发中,我们提交代码免不了要和git打交道,那么我们肯定是先从预发分支上(公司一般都用pre命名,这里为了方便演示用master)上拉去最新的代码,然后自己在上面在切一个自己的功能分支(gongeng)进行开发。 如

    2024年02月11日
    浏览(32)
  • 功能点001: git多次commit如何合并成一个commit

    通过rebase实现多次commit如何合并成一个commit

    2024年02月07日
    浏览(29)
  • 【Git】本地仓库管理远程库(GitHub)——clone(下载)、commit(添加到本地仓库)、push(提交到远程仓库)、pull(拉取)操作

    目录 使用远程仓库的目的 将本地仓库同步到git远程仓库 1.克隆远程仓库(clone) 2.新建一个文件 3.将工作区的文件添加到暂存区 4.将暂存区的文件添加到本地仓库(commit) 5.提交(同步)到远程仓库(push) 6.远程库拉取到本地库(pull) 7.团队协作开发和跨团队协作开发(开源项目) 作用:备

    2024年01月21日
    浏览(51)
  • 使用git的add提交文件到本地仓库但未commit的文件,具体找回步骤

    进入具体项目磁盘文件位置,打开git客户端命令行工具,输入【git fsck --lost-found】命令,如下图: 进入项目下的.git文件夹,找到lost-found/other文件,这个文件夹下面的文件就是丢失的文件,如下图: 把上图字母加数字的文件名称,修改成自己需要的.java文件,就ok了,如下图

    2024年02月08日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包