git 将另一个分支的所有更改合并为一次提交

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3697178/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 09:05:48  来源:igfitidea点击:

Merge all changes from another branch as a single commit

git

提问by Brad Robinson

In Git, is there a way to merge all changes from one branch into another, but squash to a single commit at the same time?

在 Git 中,有没有办法将所有更改从一个分支合并到另一个分支,但同时压缩到单个提交?

I often work on a new feature in a separate branch and will regularly commit/push - mainly for backup or to transfer what I'm working on to another machine. Mostly those commits say "Feature xxx WIP" or something redundant.

我经常在一个单独的分支中开发一个新功能,并且会定期提交/推送 - 主要用于备份或将我正在处理的内容转移到另一台机器上。大多数提交都说“Feature xxx WIP”或一些多余的东西。

Once that work is finished and I want to merge WIP branch back into master, I'd like to discard all those intermediate commits, and just a have a single clean commit.

一旦这项工作完成并且我想将 WIP 分支合并回 master,我想丢弃所有这些中间提交,并且只有一个干净的提交。

Is there an easy way to do this?

是否有捷径可寻?

Alternatively, how about a command that squashes all commits on a branch since the point where it was branched?

或者,从分支点开始压缩所有提交的命令怎么样?

回答by fseto

Another option is git merge --squash <feature branch>then finally do a git commit.

另一种选择是git merge --squash <feature branch>最后做一个git commit.

From Git merge

Git 合并

--squash

--no-squash

Produce the working tree and index state as if a real merge happened (except for the merge information), but do not actually make a commit or move the HEAD, nor record $GIT_DIR/MERGE_HEADto cause the next git commitcommand to create a merge commit. This allows you to create a single commit on top of the current branch whose effect is the same as merging another branch (or more in case of an octopus).

--squash

--no-squash

生成工作树和索引状态,就好像发生了真正的合并(合并信息除外),但实际上不进行提交或移动HEAD,也不记录 $GIT_DIR/MERGE_HEAD以导致下一个 git commit命令创建合并提交。这允许您在当前分支之上创建单个提交,其效果与合并另一个分支相同(如果是章鱼则更多)。

回答by Brad Robinson

Found it! Merge command has a --squashoption

找到了!合并命令有一个--squash选项

git checkout master
git merge --squash WIP

at this point everything is merged, possibly conflicted, but not committed. So I can now:

在这一点上,一切都被合并了,可能是冲突的,但没有提交。所以我现在可以:

git add .
git commit -m "Merged WIP"

回答by fseto

Try git rebase -i masteron your feature branch. You can then change all but one 'pick' to 'squash' to combine the commits. See squashing commits with rebase

试试git rebase -i master你的功能分支。然后,您可以将除一个 'pick' 以外的所有内容更改为 'squash' 以合并提交。查看使用 rebase 压缩提交

Finally, you can then do the merge from master branch.

最后,您可以从 master 分支进行合并。

回答by raratiru

Using git merge --squash <feature branch>as the accepted answersuggests does the trick but it will not show the merged branch as actually merged.

使用git merge --squash <feature branch>接受的答案可以解决问题,但它不会将合并的分支显示为实际合并。

Therefore an even better solution is to:

因此,更好的解决方案是:

  • Create a new branch from the latest master
  • Merge <feature branch>into the above using git merge --squash
  • Merge the newly created branch into master
  • 从最新的 master 创建一个新分支
  • 合并<feature branch>到上面使用git merge --squash
  • 将新创建的分支合并到 master

This wikiexplains the procedure in detail.

这个 wiki详细解释了这个过程。

回答by Stephen Crosby

I have created my own git alias to do exactly this. I'm calling it git freebase! It will take your existing messy, unrebasable feature branch and recreate it so that it becomes a new branch with the same name with its commits squashed into one commit and rebased onto the branch you specify (master by default). At the very end, it will allow you to use whatever commit message you like for your newly "freebased" branch.

我已经创建了自己的 git 别名来做到这一点。我叫它git freebase!它将采用您现有的杂乱的、不可rebase 的功能分支并重新创建它,以便它成为一个具有相同名称的新分支,其提交被压缩为一个提交并重新基于您指定的分支(默认情况下为 master)。最后,它将允许您为新的“freebased”分支使用您喜欢的任何提交消息。

Install it by placing the following alias in your .gitconfig:

通过在 .gitconfig 中放置以下别名来安装它:

[alias]
  freebase = "!f() { \
    TOPIC="$(git branch | grep '\*' | cut -d ' ' -f2)"; \
    NEWBASE="${1:-master}"; \
    PREVSHA1="$(git rev-parse HEAD)"; \
    echo "Freebaseing $TOPIC onto $NEWBASE, previous sha1 was $PREVSHA1"; \
    echo "---"; \
    git reset --hard "$NEWBASE"; \
    git merge --squash "$PREVSHA1"; \
    git commit; \
  }; f"

Use it from your feature branch by running: git freebase <new-base>

通过运行从您的功能分支使用它: git freebase <new-base>

I've only tested this a few times, so read it first and make sure you want to run it. As a little safety measure it does print the starting sha1 so you should be able to restore your old branch if anything goes wrong.

我只测试了几次,所以先阅读它并确保你想运行它。作为一项安全措施,它确实打印了起始 sha1,因此如果出现任何问题,您应该能够恢复旧分支。

I'll be maintaining it in my dotfiles repo on github: https://github.com/stevecrozz/dotfiles/blob/master/.gitconfig

我将在 github 上的 dotfiles 存储库中维护它:https: //github.com/stevecrozz/dotfiles/blob/master/.gitconfig

回答by Arjun Mullick

git merge --squash <feature branch>is a good option .The "git commit" tells you all feature branch commit message with your choice to keep it .

git merge --squash <feature branch>是一个不错的选择。“git commit”告诉您所有功能分支提交消息,并选择保留它。

For less commit merge .

对于较少提交合并。

git merge do x times --git reset HEAD^ --soft then git commit .

git merge do x 次 --git reset HEAD^ --soft 然后 git commit 。

Risk - deleted files may come back .

风险删除的文件可能会回来。

回答by NamshubWriter

You can do this with the "rebase" command. Let's call the branches "main" and "feature":

您可以使用“rebase”命令执行此操作。让我们称分支为“main”和“feature”:

git checkout feature
git rebase main

The rebase command will replay all of the commits on "feature" as one commit with a parent equal to "main".

rebase 命令会将“功能”上的所有提交重放为父项等于“main”的一次提交。

You might want to run git merge mainbefore git rebase mainif "main" has changed since "feature" was created (or since the most recent merge). That way, you still have your full history in case you had a merge conflict.

如果自创建“功能”(或自最近的合并以来)以来“主”已更改,您可能希望在此git merge main之前运行git rebase main。这样,您仍然拥有完整的历史记录,以防发生合并冲突。

After the rebase, you can merge your branch to main, which should result in a fast-forward merge:

在 rebase 之后,您可以将分支合并到主分支,这应该会导致快进合并:

git checkout main
git merge feature

See the rebasepage of Understanding Git Conceptuallyfor a good overview

请参阅从概念理解 Gitrebase页面以获得一个很好的概述