简体   繁体   English

推送后如何压缩 Bitbucket 上的提交?

[英]How to squash commits on Bitbucket after they have been pushed?

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分支中的几个文件。

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.第二个分支可以根据需要向远程服务器推送尽可能多的内容。

  1. 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}
  2. Identify the first commit where your personal branch diverged from an existing CEF branch.确定您的个人分支与现有 CEF 分支不同的第一个提交。

     # Replace {BranchName} with your new branch name. # Replace "master" with a different CEF branch as appropriate # (eg "2272", "2171", etc). $ git merge-base {BranchName} master
  3. Start an interactive rebase using the commit hash returned from step 2.使用从步骤 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 else
  4. Change all but the first line to say squash instead of pick .将除第一行之外的所有内容更改为squash而不是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 else
  5. Save the changes and close the file (Can be done by pressing esc and type: :wq .保存更改并关闭文件(可以通过按esc并键入: :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.重写提交消息,然后保存更改并关闭文件。

  6. 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

There is a simpler way.有一个更简单的方法。

If you are absolutely certain that no one will ever use that specific branch you can do the following:如果您绝对确定没有人会使用该特定分支,则可以执行以下操作:

  1. Create a local branch that has everyone's commits.创建一个包含每个人提交的本地分支。
  2. do git log on the local branch to determine the hash of the non-branch commit preceding the first branch commit.在本地分支上执行 git log 以确定第一个分支提交之前的非分支提交的哈希值。
  3. Do: git reset --soft <hash>做: git reset --soft <hash>
  4. Do: git commit to create the single commit message that you want.做: git commit 创建您想要的单个提交消息。
  5. Do: git rebase -i to move your local branch to the tip of master.做: git rebase -i将您的本地分支移动到 master 的尖端。
  6. Fix any merge conflicts.修复任何合并冲突。
  7. git push your changes to your remote branch used for the PR. git push 您的更改到用于 PR 的远程分支。 Use -f for force push if it already exists.如果已经存在,请使用 -f 进行强制推送。

Use git rebase !使用git rebase

Bitbucket use the Git software. Bitbucket使用Git软件。

alex said 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 中使用这些命令:

  1. git rebase -i yourbranchname
  2. A file in a editor program will be automatcally open.编辑器程序中的文件将自动打开。
  3. Change all commits from " pick " to " fixup " but one commit must have " pick "!将所有提交从“ pick ”更改为“ fixup ”,但一个提交必须有“ pick ”!
  4. Save the file and close.保存文件并关闭。
  5. git push -f origin yourbranchname

Helpful resources有用的资源

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.现在您可以强制将您的分支推送到您自己的另一个项目的分支,并尝试发出另一个拉取请求。

...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.如果您已经推送它们,则需要使用-f选项强制推送。 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 new history.请注意,这是不受欢迎的,因为其他任何取消这些更改的人都必须跳过可能与历史记录重新同步的障碍。

There may be a way to do it in SourceTree.在 SourceTree 中可能有一种方法可以做到这一点。

Further reading . 进一步阅读

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=$1

 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM