博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Git将我的最后一个X提交一起压缩
阅读量:2289 次
发布时间:2019-05-09

本文共 9979 字,大约阅读时间需要 33 分钟。

如何使用Git将最后的X个提交一起压缩为一个提交?


#1楼

根据 ,

从bash添加全局“ squash”别名:(或Windows上的Git Bash)

git config --global alias.squash '!f(){ git reset --soft HEAD~${1} && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"; };f'

...或使用Windows的命令提示符:

git config --global alias.squash "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"

您的~/.gitconfig现在应包含以下别名:

[alias]    squash = "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"

用法:

git squash N

...会自动将最后N提交(包括首尾)压缩在一起。

注意:结果提交消息按顺序是所有压缩的提交的组合。 如果您对此不满意,可以随时git commit --amend手动修改它。 (或者,编辑别名以符合您的口味。)


#2楼

我建议尽可能避免git reset特别是对于Git-novices。 除非您真的需要基于多个提交使流程自动化,否则会有一种不太常见的方式...

  1. 将要压缩的提交放在工作分支上(如果尚未提交)-为此使用gitk
  2. 签出目标分支(例如“ master”)
  3. git merge --squash (working branch name)
  4. git commit

提交消息将根据壁球预先填充。


#3楼

根据我发现此方法对我的用例更容易。

我的'dev'分支比'origin / dev'提前了96次提交(因此这些提交尚未推送到远程)。

我想将这些提交压缩为一,然后再进行更改。 我更喜欢将分支重置为“ origin / dev”状态(这将取消暂存96次提交中的所有更改),然后立即提交更改:

git reset origin/devgit add --allgit commit -m 'my commit message'

#4楼

我发现一个更通用的解决方案不是指定“ N”个提交,而是要在其顶部压入的branch / commit-id。 与将提交计数到特定提交为止相比,这种方法更不容易出错-只需直接指定标签,或者如果您真的想计数,则可以指定HEAD〜N。

在我的工作流程中,我启动了一个分支,我对该分支的第一次提交总结了目标(即通常是我将其作为功能的“最终”消息推送到公共存储库的内容。)我要做的是将git squash master回到第一条消息,然后我准备推送。

我使用别名:

squash = !EDITOR="\"_() { sed -n 's/^pick //p' \"\\$1\"; sed -i .tmp '2,\\$s/^pick/f/' \"\\$1\"; }; _\"" git rebase -i

这将在此之前转储被压缩的历史记录,这使您有机会通过还原控制台中的旧提交ID来进行恢复。 (Solaris用户注意到它使用了GNU sed -i选项,Mac和Linux用户应该可以使用此选项。)


#5楼

如果您位于从Golden Repository( golden_repo_name )克隆的远程分支(称为feature-branch )上,则可以使用以下方法将提交golden_repo_name为一个:

  1. 签出黄金仓库

    git checkout golden_repo_name
  2. 从其创建一个新分支(黄金仓库),如下所示

    git checkout -b dev-branch
  3. 壁球与您已经拥有的本地分支合并

    git merge --squash feature-branch
  4. 提交更改(这将是在开发分支中进行的唯一提交)

    git commit -m "My feature complete"
  5. 将分支推送到本地存储库

    git push origin dev-branch

#6楼

如果使用TortoiseGit,则可以将功能Combine to one commit

  1. 打开TortoiseGit上下文菜单
  2. 选择Show Log
  3. 在日志视图中标记相关的提交
  4. 从上下文菜单中选择“ Combine to one commit

此功能自动执行所有必要的单个git步骤。 不幸的是,仅适用于Windows。


#7楼

如果您使用的是 ,请选择要与其父级合并的提交,然后按S。 您每次提交都必须执行一次,但是比提出正确的命令行命令要简单得多。 特别是如果您只偶尔执行一次。


#8楼

感谢我发现您可以使用此命令来压缩最近的3次提交:

git rebase -i HEAD~3

这很方便,因为即使您在没有跟踪信息/远程回购的本地分支机构中也可以使用。

该命令将打开交互式rebase编辑器,该编辑器随后将允许您按常规重新排序,压缩,重新编写单词等。


使用交互式基础编辑器:

交互式基础编辑器显示最后三个提交。 当运行命令git rebase -i HEAD~3时,此约束由HEAD~3确定。

最新提交HEAD最初显示在第1行。以#开头的行是注释/文档。

显示的文档非常清晰。 在任何给定的行上,您都可以将命令从pick更改为您选择的命令。

我更喜欢使用命令fixup因为这可以将提交的更改“压榨”到上一行的提交中,并丢弃提交的消息。

由于第1行的提交为HEAD ,在大多数情况下,您将其保留为pick 。 您不能使用squashfixup因为没有其他提交可以将提交压缩到其中。


#9楼

如果要将每个提交压缩为单个提交(例如,首次公开发布项目时),请尝试:

git checkout --orphan 
git commit

#10楼

为此,您可以使用以下git命令。

git rebase -i HEAD~n

n(此处为4)是最后提交的次数。 然后您有以下选择,

pick 01d1124 Message....pick 6340aaa Message....pick ebfd367 Message....pick 30e0ccb Message....

像下面这样更新

p 01d1124 Message....s 6340aaa Message....s ebfd367 Message....s 30e0ccb Message....

有关详细信息,请单击

祝好运!!


#11楼

有问题的是,“最后”的含义可能是模棱两可的。

例如git log --graph输出以下内容(简化):

* commit H0|* merge|\| * commit B0| || * commit B1| | * | commit H1| |* | commit H2|/|

然后按时间的最后提交是H0,合并,B0。 要压缩它们,您将必须基于提交H1重新建立合并的分支。

问题在于H0包含H1和H2(通常在合并之前和分支之后会有更多提交),而B0则没有。 因此,您至少必须管理来自H0,合并,H1,H2,B0的更改。

可以使用rebase,但使用的方式与其他提到的答案不同:

rebase -i HEAD~2

这将为您显示选择选项(如其他答案中所述):

pick B1pick B0pick H0

将壁球而不是接球放到H0:

pick B1pick B0s H0

保存并退出rebase之后,将在H1之后依次应用提交。 这意味着它将要求您再次解决冲突(其中HEAD首先为H1,然后在应用提交时累积提交)。

重置完成后,您可以选择压缩的H0和B0消息:

* commit squashed H0 and B0|* commit B1| * commit H1|* commit H2|

PS:如果您只是对BO进行了一些重置:(例如,使用reset --mixed ,在这里进行了详细说明):

git reset --mixed hash_of_commit_B0git add .git commit -m 'some commit message'

那么您将压倒H0,H1,H2的B0更改(在分支之后和合并之前完全放弃提交更改)。


#12楼

真正方便的是:

找到要d43e15的提交哈希,例如d43e15

现在使用

git reset d43e15git commit -am 'new commit name'

#13楼

1)确定提交短哈希

# git log --pretty=oneline --abbrev-commitabcd1234 Update to Fix for issue Bcdababcd Fix issue Bdeab3412 Fix issue A....

在这里,甚至git log --oneline也可以用来获取短哈希。

2)如果您要压缩(合并)最后两次提交

# git rebase -i deab3412

3)这将打开一个用于合并的nano编辑器。 它看起来像下面

....pick cdababcd Fix issue Bpick abcd1234 Update to Fix for issue B....

4)重命名字picksquash这是之前存在abcd1234 。 重命名后,应如下所示。

....pick cdababcd Fix issue Bsquash abcd1234 Update to Fix for issue B....

5)现在保存并关闭nano编辑器。 按ctrl + o ,然后按Enter保存。 然后按ctrl + x退出编辑器。

6)然后,再次打开nano编辑器以更新注释,必要时进行更新。

7)现在已成功将其压扁,您可以通过检查日志进行验证。

# git log --pretty=oneline --abbrev-commit1122abcd Fix issue Bdeab3412 Fix issue A....

8)现在按回购。 注意在分支名称前添加+号。 这意味着强制推动。

# git push origin +master

注意:这是基于在ubuntu shell上使用git的基础。 如果您使用不同的操作系统( WindowsMac ),则除了编辑器外,上述命令相同。 您可能会获得不同的编辑器。


#14楼

git rebase -i HEAD^^

^的数量是X

(在这种情况下,压缩最后两个提交)


#15楼

除了其他出色的答案,我想补充一下git rebase -i总是使我对提交顺序感到困惑-从旧到新,反之亦然? 这是我的工作流程:

  1. git rebase -i HEAD~[N] ,其中N是我要加入的提交数, 从最近一次开始 。 因此git rebase -i HEAD~5意味着“将最后5次提交压缩为一个新提交”;
  2. 编辑器弹出,显示我要合并的提交列表。 现在,它们以相反的顺序显示:较早的提交位于顶部。 将其中的所有提交标记为“ squash”或“ s”, 除了第一个/较旧的提交:它将被用作起点。 保存并关闭编辑器;
  3. 编辑器会再次弹出,并带有新提交的默认消息:根据您的需要进行更改,保存并关闭。 壁球完成!

资料和其他读物: , 。


#16楼

我认为最简单的方法是从master分支上创建一个新分支,然后合并feature分支的--squash。

git checkout mastergit checkout -b feature_branch_squashedgit merge --squash feature_branch

然后,您已准备好所有更改。


#17楼

与这样的工作流程有关的问题的答案呢?

  1. 许多本地提交, 混合有来自master的多个合并
  2. 最终推向远程
  3. 公关并由审稿人合并为硕士。 (是的,在PR之后,开发人员merge --squash会更容易,但是团队认为这样做会减慢该过程。)

我在此页面上没有看到这样的工作流程。 (这也许是我的眼睛。)如果我正确理解了rebase ,则多次合并将需要多个冲突解决方案 。 我什至不想考虑!

因此,这似乎对我们有用。

  1. git pull master
  2. git checkout -b new-branch
  3. git checkout -b new-branch-temp
  4. 在本地编辑和提交大量内容,定期合并母版
  5. git checkout new-branch
  6. git merge --squash new-branch-temp //将所有更改置于阶段
  7. git commit 'one message to rule them all'
  8. git push
  9. 审阅者执行PR并合并到母版。

#18楼

是好的,但是我对此感到不安全,所以我决定添加一些屏幕截图。

步骤0:git log

使用git log查看您的位置。 最重要的是,找到您不想压榨的第一个提交的提交哈希。 所以只有:

步骤1:git rebase

在我的情况下,执行 :

$ git rebase -i 2d23ea524936e612fae1ac63c95b705db44d937d

第2步:选择/挤压您想要的东西

就我而言,我想压缩第一次提交中的所有内容。 顺序是git log ,与git log的顺序完全相反。 就我而言,我想要:

步骤3:调整讯息

如果您只选择了一个提交,但压榨了其余的提交,则可以调整一个提交消息:

而已。 保存此( :wq )后,就完成了。 用git log看一下。


#19楼

在分支中,您想合并提交,运行:

git rebase -i HEAD~(n number of commits back to review)

例:

git rebase -i HEAD~1

这将打开文本编辑器,并且如果您希望将这些提交合并在一起,则必须在每个提交前面将“ pick”切换为“ squash”。 从文档:

p,选择=使用提交

s,squash =使用提交,但可以合并到先前的提交中

例如,如果您希望将所有提交合并为一个,则“ pick”是您进行的第一个提交,所有将来的提交(放置在第一个之后)应设置为“ squash”。 如果使用vim,请在插入模式下使用:x保存并退出编辑器。

然后继续进行变基:

git rebase --continue

有关此方法以及重写提交历史记录的其他方法的更多信息,请参见此


#20楼

使用git rebase -i <after-this-commit>并在第二次及以后的提交中将“ pick”替换为“ squash”或“ fixup”,如中 。

在此示例中, <after-this-commit>是SHA1哈希,或者是当前分支的HEAD的相对位置,从该分支分析提交的rebase命令。 例如,如果用户过去希望查看当前HEAD的5个提交,则命令为git rebase -i HEAD~5


#21楼

您可以为此使用git merge --squash ,它比git rebase -i稍微好一点。 假设您在master上,并且想要将最后12次提交压缩为1次。

警告:首先请确保您已完成工作-检查git status是否干净(因为git reset --hard将丢弃暂存和未暂存的更改)

然后:

# Reset the current branch to the commit just before the last 12:git reset --hard HEAD~12# HEAD@{1} is where the branch was just before the previous command.# This command sets the state of the index to be as it would just# after a merge from that commit:git merge --squash HEAD@{1}# Commit those squashed changes.  The commit message will be helpfully# prepopulated with the commit messages of all the squashed commits:git commit

的更详细地介绍了--squash选项。


更新:此方法相对于Chris Johnsen在建议的更简单的git reset --soft HEAD~12 && git commit的唯一真正优势是,您得到的提交消息中都包含您要压缩的每个提交消息。


#22楼

要将最后10次提交压缩为1次单次提交:

git reset --soft HEAD~10 && git commit -m "squashed commit"

如果您还想使用压缩的提交来更新远程分支:

git push -f

#23楼

这是超级骗子的迷糊,但以一种很酷的方式,所以我将它扔进去:

GIT_EDITOR='f() { if [ "$(basename $1)" = "git-rebase-todo" ]; then sed -i "2,\$s/pick/squash/" $1; else vim $1; fi }; f' git rebase -i foo~5 foo

翻译:为git提供一个新的“编辑器”,如果要编辑的文件名是git-rebase-todo (交互式变基提示),则将除第一个“ pick”外的所有内容都更改为“ squash”,否则生成vim-这样当系统提示您编辑压缩的提交消息时,您将获得vim。 (很明显,我压缩了分支foo上的最后五个commit,但是您可以根据需要更改它。)

我可能会做 。


#24楼

您可以很容易地做到这一点,而无需git rebasegit merge --squash 。 在此示例中,我们将压缩最后3次提交。

如果您想从头开始编写新的提交消息,则满足以下条件:

git reset --soft HEAD~3 &&git commit

如果要开始使用现有提交消息的串联来编辑新的提交消息(即类似于pick / squash / squash /…/ squash git rebase -i指令列表的开头),则需要提取这些消息并将它们传递给git commit

git reset --soft HEAD~3 && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"

这两种方法都以相同的方式将最后三个提交压缩为单个新提交。 软重置只是将HEAD重新指向您不想挤压的最后一次提交。 软复位既不会触及索引也不会影响工作树,从而使索引处于您的新提交所需的状态(即,它已经具有您要“丢弃”的提交中的所有更改)。


#25楼

首先,我按以下方式查找功能分支和当前主分支之间的提交次数

git checkout mastergit rev-list master.. --count

然后,我基于我的功能分支创建另一个分支,保持my-feature分支不变。

最后,我跑

git checkout my-featuregit checkout -b my-rebased-featuregit checkout mastergit checkout my-rebased-featuregit rebase mastergit rebase head^x -i// fixup/pick/rewritegit push origin my-rebased-feature -f // force, if my-rebased-feature was ever pushed, otherwise no need for -f flag// make a PR with clean history, delete both my-feature and my-rebased-feature after merge

希望能有所帮助,谢谢。


#26楼

⚠️警告:“我最近的X次提交”可能是模棱两可的。

(MASTER)  Fleetwood Mac            Fritz      ║                    ║  Add Danny  Lindsey     Stevie           Kirwan  Buckingham    Nicks                                                    ║         ╚═══╦══════╝     Add Christine       ║             Perfect      Buckingham      ║           Nicks                LA1974══════════╝                                          ║                        ║                      Bill <══════ YOU ARE EDITING HERE  Clinton        (CHECKED OUT, CURRENT WORKING DIRECTORY)

在这个非常简写的历史库已经打开拉请求中的比尔·克林顿合并提交到原始( MASTER )弗利特伍德Mac的承诺。

您打开了一个拉取请求,并在GitHub上看到以下内容:

四次提交:

  • 添加丹尼·基万(Danny Kirwan)
  • 添加克里斯汀完美
  • LA1974
  • 比尔·克林顿

认为没有人会愿意阅读完整的存储库历史记录。 (实际上有一个存储库,单击上面的链接!)您决定压缩这些提交。 所以你去运行git reset --soft HEAD~4 && git commit 。 然后您git push --forcegit push --force到GitHub上以清理您的PR。

那会发生什么呢? 您刚刚完成了一次从Fritz到Bill Clinton的提交。 因为您忘记了昨天您正在从事该项目的白金汉尼克斯版本。 git log与您在GitHub上看到的不匹配。

🐻故事的道德

  1. 找到你想要得到确切文件, git checkout他们
  2. 找到您想要保留在历史记录中的确切先前提交,然后git reset --soft
  3. 进行git commit ,直接从from变形到to

#27楼

假设您当前在要压扁的分支上,简单的单行代码始终可以工作,master是它源自的分支,并且最新提交包含您希望使用的提交消息和作者:

git reset --soft $(git merge-base HEAD master) && git commit --reuse-message=HEAD@{1}

#28楼

如果您使用的是GitLab,则只需单击Merge Request中的Squash选项,如下所示。 提交消息将成为合并请求的标题。


#29楼

例如,如果您想将最后3次提交压缩为分支机构(远程存储库)中的单个提交,例如: :

我所做的是

  1. git reset --soft Head〜3 &&
  2. git提交
  3. git push origin(branch_name)--force

#30楼

如果您不关心中间提交的提交消息,则可以使用

git reset --mixed 
git commit -a --amend

转载地址:http://uvdnb.baihongyu.com/

你可能感兴趣的文章
Lightoj1140——How Many Zeroes?(数位dp)
查看>>
Lightoj1068——Investigation(数位dp)
查看>>
Lightoj1205——Palindromic Numbers(数位dp+回文数)
查看>>
hihoCoder1385——A Simple Job(模拟)
查看>>
hdu1045——Fire Net(二分图+行列匹配)
查看>>
hdu2444——The Accomodation of Students(判断二分图+匈牙利算法)
查看>>
hdu1083——Courses(匈牙利算法)
查看>>
poj2594——Treasure Exploration(闭包+最小路径覆盖)
查看>>
poj3020——Antenna Placement(最小边覆盖)
查看>>
hdu1029——Ignatius and the Princess IV
查看>>
poj1035——Spell checker
查看>>
poj3080——Blue Jeans(字串)
查看>>
linux信号处理
查看>>
dwarf 栈解析格式小结
查看>>
kvm 监控内存,替换页表(linux版的win VT晶核)(这个整复杂了,不用小内核也可以实现,留着吧,主要记录了bootLoad的启动过程)
查看>>
KVM 代码详解
查看>>
cve-2019-15666 xfrm_policy
查看>>
硬件虚拟化之vmm接管异常中断
查看>>
blue-pill代码解读
查看>>
intel 虚拟化手册解读
查看>>