git 推送后如何压缩 Bitbucket 上的提交?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34673683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to squash commits on Bitbucket after they have been pushed?
提问by Joshua
I am currently working on a project with multiple others. The problem is that we created a fork of an existed project and need to squash all our commits from after the forking process to a single commit for a pull-request on Bitbucket.
我目前正在与多个其他人一起开展一个项目。问题是我们创建了一个现有项目的分叉,并且需要将分叉过程之后的所有提交压缩到Bitbucket上的拉取请求的单个提交。
Is there any way (preferably using SourceTree, otherwise terminal) to squash already pushed commits to a single commit, such that the history within Bitbucket of all the commits are also only that one commit plus the commits which were already there before we forked the project?
有没有办法(最好使用SourceTree,否则使用终端)来压缩已经推送到单个提交的提交,这样 Bitbucket 中所有提交的历史记录也只是一个提交加上我们分叉项目之前已经存在的提交?
Take as example just a simple project with a few files in only a master
branch.
以一个简单的项目为例,只有一个master
分支中有几个文件。
采纳答案by Joshua
Found a nice summary of the posted answers. This one is a bit more clear: squash pushed commits. It will require creating a second branch upon the creation of the fork. This second branch can have as many pushes to the remote server as needed.
找到了对已发布答案的一个很好的总结。这个更清楚一点: 壁球推送提交。它需要在创建分叉时创建第二个分支。第二个分支可以根据需要向远程服务器推送尽可能多的内容。
Create a new personal branch that will be squashed.
# Start with the existing personal branch that contains all of your commits.
$git checkout {ExistingBranchName}
# Create a new personal branch that will be squashed.
$git checkout -b {BranchName}Identify the first commit where your personal branch diverged from an existing CEF branch.
# Replace {BranchName} with your new branch name.
# Replace "master" with a different CEF branch as appropriate (e.g. "2272", "2171", etc).
$git merge-base {BranchName} masterStart an interactive rebase using the commit hash returned from step 2.
$git rebase --interactive {hash}
This will launch a text editor with a list of all commits in your personal branch. It should look something like this:
pick 59d2a23 Initial implementation
pick 752ae4c Add more features
pick cd302a3 Fix something
pick 5410de3 Fix something elseChange all but the first line to say "squash" instead of "pick". The contents should now look like this:
pick 59d2a23 Initial implementation
squash 752ae4c Add more features
squash cd302a3 Fix something
squash 5410de3 Fix something elseSave the changes and close the file (Can be done by pressing
esc
and type::wq
.
A new file will now open containing the commit messages from all of the commits. Reword the commit message then save the changes and close the file.Push the modifications to your personal remote repository.
# If the branch has already been pushed to the remote repository you will need to add the--force
argument.
git push origin {BranchName}or git push origin {BranchName} --force
创建一个将被压缩的新个人分支。
# 从包含所有提交的现有个人分支开始。
$git checkout {ExistingBranchName}
# 创建一个将被压扁的新个人分支。
$git checkout -b {BranchName}确定您的个人分支与现有 CEF 分支不同的第一个提交。
# 将 {BranchName} 替换为您的新分支名称。
# 根据需要将“master”替换为不同的 CEF 分支(例如“2272”、“2171”等)。
$git merge-base {BranchName} master使用从第 2 步返回的提交散列启动交互式变基。
$git rebase --interactive {hash}
这将启动一个文本编辑器,其中包含您个人分支中所有提交的列表。它应该看起来像这样:
pick 59d2a23 初始实现
pick 752ae4c 添加更多功能
pick cd302a3 修复某些内容
pick 5410de3 修复其他内容将除第一行之外的所有内容更改为“壁球”而不是“选择”。内容现在应如下所示:
pick 59d2a23 初始实现
squash 752ae4c 添加更多功能
squash cd302a3 修复一些内容
squash 5410de3 修复其他内容保存更改并关闭文件(可以通过按下
esc
并输入:来完成:wq
。
现在将打开一个新文件,其中包含来自所有提交的提交消息。改写提交消息,然后保存更改并关闭文件。将修改推送到您的个人远程存储库。
# 如果分支已经被推送到远程仓库,你需要添加--force
参数。
git push origin {BranchName}或git push origin {BranchName} --force
回答by Alwyn Schoeman
There is a simpler way.
有一个更简单的方法。
If you are absolutely certain that no one will ever use that specific branch you can do the following:
如果您绝对确定没有人会使用该特定分支,则可以执行以下操作:
- Create a local branch that has everyone's commits.
- do git log on the local branch to determine the hash of the non-branch commit preceding the first branch commit.
- Do:
git reset --soft <hash>
- Do: git commit to create the single commit message that you want.
- Do:
git rebase -i
to move your local branch to the tip of master. - Fix any merge conflicts.
- git push your changes to your remote branch used for the PR. Use -f for force push if it already exists.
- 创建一个包含每个人提交的本地分支。
- 在本地分支上执行 git log 以确定第一个分支提交之前的非分支提交的哈希值。
- 做:
git reset --soft <hash>
- 做: git commit 创建您想要的单个提交消息。
- 做:
git rebase -i
将你的本地分支移动到 master 的尖端。 - 修复任何合并冲突。
- git push 您的更改到用于 PR 的远程分支。如果已经存在,请使用 -f 进行强制推送。
回答by alex
...we created a fork of an existed project and need to squash all our commits from after the forking process to a single commit for a pull-request on Bitbucket
...我们创建了一个现有项目的分叉,并且需要将分叉过程之后的所有提交压缩到 Bitbucket 上的拉取请求的单个提交
Note that you don't need a single commit for a pull request. A bunch of commits can constitute a pull request.
请注意,您不需要为拉取请求进行一次提交。一堆提交可以构成一个拉取请求。
Is there any way (preferably using SourceTree, otherwise terminal) to squash already pushed commits to a single commit?
有什么方法(最好使用 SourceTree,否则使用终端)将已经推送的提交压缩到单个提交?
Yes, you can use an interactive rebase git rebase -i
.
是的,您可以使用交互式 rebase git rebase -i
。
You can then mark the commits you want to squash (follow the on-screen instructions that appear in your editor) and then write a new commit message when you have finished (use git rebase --continue
after each commit you have worked on).
然后,您可以标记要压缩的提交(按照出现在编辑器中的屏幕说明进行操作),然后在完成后编写新的提交消息(git rebase --continue
在您处理过的每次提交后使用)。
If you have pushed them already, you will need to force push with the -f
option. Note that this is frowned upon, as anyone else that has pulled down these changes has to jump through hoops potentially to resync with the newhistory.
如果您已经推送它们,则需要使用该-f
选项强制推送。请注意,这是不受欢迎的,因为其他任何撤消这些更改的人都必须跳过可能与新历史重新同步的障碍。
There may be a way to do it in SourceTree.
在 SourceTree 中可能有一种方法可以做到这一点。
回答by Suriyaa
Use git rebase
!
使用git rebase
!
alexsaid it already in his post: Use the
git rebase -i ourbranchname
command!
亚历克斯已经在他的帖子中说过:使用
git rebase -i ourbranchname
命令!
Commands
命令
Use these commands in the terminal, command prompt or in your cmd:
在终端、命令提示符或 cmd 中使用这些命令:
git rebase -i yourbranchname
- A file in a editor program will be automatcally open.
- Change all commits from "
pick
" to "fixup
" but one commit must have "pick
"! - Save the file and close.
git push -f origin yourbranchname
git rebase -i yourbranchname
- 编辑器程序中的文件将自动打开。
- 将所有提交从“
pick
”更改为“fixup
”,但一个提交必须具有“pick
”! - 保存文件并关闭。
git push -f origin yourbranchname
Helpful resources
有用的资源
回答by Ferrybig
Rebasing is easy to do with SourceTree, in sourcetree select the commit that you based your work on, then press the right mouse button.
使用 SourceTree 可以轻松进行重新定位,在 sourcetree 中选择您基于工作的提交,然后按鼠标右键。
Then a menu will popup, select "interactively rebase children of "
然后会弹出一个菜单,选择“交互式变基”的孩子
This will open a screen where we can select what to do with every commit. Since we want to squash every commit together, we click the top commit and select the button "Squash with previous" at the bottom of the screen. Sourcetree will update the top screen in response to the actions you did so you can see its doing what you want.
这将打开一个屏幕,我们可以在其中选择对每次提交执行的操作。由于我们希望将每个提交压缩在一起,因此我们单击顶部提交并选择屏幕底部的“与上一个压缩”按钮。Sourcetree 将根据您所做的操作更新顶部屏幕,以便您可以看到它在做什么。
Before:
前:
After:
后:
Usually, you also want to change the message of the commit when you squash them together, double click on the message to change it. If you are done with the changes, press "ok" at the right bottom corner. Source Tree will now rebase the history for you.
通常,您还希望在将它们压缩在一起时更改提交的消息,双击消息进行更改。如果您完成了更改,请按右下角的“确定”。源树现在将为您重新设置历史记录。
Finished result:
完成结果:
Now you can force push your branch to your own fork of the other project and try to make another pull request.
现在您可以强制将您的分支推送到您自己的另一个项目的分支,并尝试发出另一个拉取请求。
回答by Ravi Prajapati
You can use this script for squash all commit of current branch and with final commit message.
您可以使用此脚本压缩当前分支的所有提交和最终提交消息。
#!/bin/sh
# brief: This script should be run from within your git repo. You need to have your feature branch
# checked out. This will squash all the commits on your feature branch (assuming you
# branched from master). Then you can just use the github PR UI to merge the PR in. You need to have
# feature branch checked out when you run this script (git checkout feature branch).
# usage: git-helper-squash-all-commits <final commit messsage ex: "reorganizing directory structure"
# example: git-helper-squash-all-commits "reorganizing directory structure"
set -ex
FINAL_COMMIT_MESSAGE=
BRANCH_YOU_BRANCHED_FROM=master
CURRENT_BRANCH=`git rev-parse --abbrev-ref HEAD`
COMMIT_HASH=`git merge-base HEAD $BRANCH_YOU_BRANCHED_FROM`
git reset --soft $COMMIT_HASH
git commit -am "$FINAL_COMMIT_MESSAGE"
git push origin $CURRENT_BRANCH --force