git 在推送之前将多个提交合并为一个

des4xlb0  于 2023-01-15  发布在  Git
关注(0)|答案(7)|浏览(297)

这个问题不仅涉及到如何完成这个任务,还涉及到这样做是Git的好习惯还是坏习惯。
假设我在本地完成了master分支上的大部分工作,但是我创建了一个主题分支,我将其命名为“topical_xFeature”。在处理“topical_xFeature”和来回切换到master分支上做其他工作的过程中,我在“topical_xFeature”分支上做了不止一次提交,但是在每次提交之间,我没有做任何推送。

首先,你会考虑这个不好的做法吗?坚持每次推送每个分支一次提交不是更明智吗?在什么情况下,在进行推送之前,在一个分支上有多个提交是好的?
第二个,我怎样才能最好地完成把topical_xFeature分支上的多个提交放到master分支上进行推送呢?不去担心它,只在多个提交被推送的地方进行推送,这会不会很麻烦,或者把提交合并成一个然后再推送会不会更不麻烦?再问一次,怎么做?

gajydyqb

gajydyqb1#

对于你的第一个问题,不,一次推送多个提交并没有错。很多时候,你可能想把你的工作分解成几个小的,合乎逻辑的提交,但是只有当你觉得整个系列都准备好了的时候,才把它们推上去。或者你可能在离线的时候在本地进行几个提交。并且当你再次连接时,你可以推送它们。没有理由限制你每次推送一个提交。
我通常发现,让每个提交保持一个单一的、逻辑的、一致的更改是一个好主意,其中包括它工作所需的一切(所以,它不会让你的代码处于中断状态)。如果你有两次提交,但如果你只应用了第一次,它们会导致代码中断,将第二次提交压缩到第一次提交中可能是一个好主意。2但是如果你有两次提交,每一次都做了合理的修改,那么将它们作为单独的提交推送也是可以的。
如果你确实想把几个提交挤在一起,你可以使用git rebase -i。如果你在分支topical_xFeature上,你可以运行git rebase -i master。这将打开一个编辑器窗口,其中列出了一堆以pick为前缀的提交。你可以将除了第一个提交之外的所有提交更改为squash,这将告诉Git保留所有这些更改。但是把它们压缩到第一次提交中,完成后, checkout master并合并到特性分支中:

git checkout topical_xFeature
git rebase -i master
git checkout master
git merge topical_xFeature

或者,如果您只想将topical_xFeature中的所有内容压缩到master中,则只需执行以下操作:

git checkout master
git merge --squash topical_xFeature
git commit

你选择哪一个取决于你自己。一般来说,我不会担心有多个小的提交,但有时你不想麻烦额外的小提交,所以你只是把它们压缩成一个。

vmjh9lq9

vmjh9lq92#

这是我通常在推送代码之前将多个提交合并为一个提交的方法。
为了实现这一点,我建议您使用GIT提供的"squash"概念。
请遵循以下步骤。

    • 1)git rebase-i master**(除了master,你也可以使用一个特定的提交)

打开重定基交互式编辑器,在那里它会显示你所有的提交。基本上,你需要识别你想合并成一个提交的提交。
假设这些是您的提交,并在编辑器中显示如下内容。

pick f7f3f6d changed my name a bit    
pick 310154e updated README formatting and added blame   
pick a5f4a0d added cat-file

需要注意的是,这些提交的排列顺序与使用log命令时的排列顺序相反,也就是说,旧的提交会先显示。
2)* * 将"pick"改为"squash"**表示最后一次提交的更改。如下所示。这样做的话,你最后的两次提交将与第一次合并。

pick f7f3f6d changed my name a bit         
squash 310154e updated README formatting and added blame   
squash a5f4a0d added cat-file

如果你有很多提交要合并,你也可以使用简短形式:

p f7f3f6d changed my name a bit         
s 310154e updated README formatting and added blame   
s a5f4a0d added cat-file

对于编辑,使用"i",它将启用编辑器进行插入。请记住,最顶部(最早)的提交不能被压扁,因为没有以前的提交可供组合。因此必须选择它或使用"p"。使用"Esc"退出插入模式。
3)现在,使用以下命令保存编辑器。:wq**
当你保存它的时候,你有一个单独的提交,它引入了之前三个提交的修改。
希望这对你有帮助。

hgtggwj0

hgtggwj03#

切换到master分支并确保您是最新的。

git checkout master

git fetch这可能是接收origin/master更新所必需的(取决于你的git配置)

git pull

将特征分支合并到主分支中。

git merge feature_branch

将master分支重置为原点的状态。

git reset origin/master

Git现在把所有的修改都视为未暂存的修改。我们可以把这些修改添加为一次提交。添加.也会添加未跟踪的文件。

git add --all

git commit

参考:https://makandracards.com/makandra/527-squash-several-git-commits-into-a-single-commit

wgmfuz8q

wgmfuz8q4#

1.首先选择你希望所有事情都发生在哪个提交之后。

git reflog
5976f2b HEAD@{0}: commit: Fix conflicts
80e85a1 HEAD@{1}: commit: Add feature
b860ddb HEAD@{2}: commit: Add something

1.重置为您选择的头部(我选择了HEAD@{2}

git reset b860ddb --soft
  1. git status(只是为了确定)
    1.添加新提交
git commit -m "Add new commit"

注意:HEAD@{0}HEAD@{1}现在合并为一个提交,这也可以用于多个提交。
git reflog应再次显示:

git reflog
5976f2b HEAD@{0}: commit: Add new commit
b860ddb HEAD@{1}: commit: Add something
llew8vvj

llew8vvj5#

第一个:没有任何内容告诉你每次推送每个分支只有一次提交:推送是一种发布机制,允许您在远程存储库上发布本地历史(即提交的集合)。
第二个:在推送master之前,git merge --no-ff topical_xFeature将在master上记录您的主题工作作为一个提交。

(That这样,您可以保留topical_xFeature以备进一步的发展,您可以在master上记录为下一次合并时的单个新提交--no-ff。
如果摆脱topical_xFeature是目标,那么git merge --squash是正确的选择,正如Brian Campbell的答案中详细说明的那样。)

agxfikkp

agxfikkp6#

将多个提交自动化为一个提交的工具

as Kondal Kolipaka says.使用“git rebase -i”

“git rebase”的逻辑

当使用“git rebase -i”时,git会在当前的.git/rebase-merge目录下生成git-rebase-todo文件,然后调用git编辑器让用户编辑git-rebase-todo文件进行处理。
1.将git编辑器修改为我们提供的工具;
1.该工具处理git-rebase-todo文件。

修改默认的git编辑器

git config core.editor #show current default git editor
git config --local --replace-all  core.editor NEW_EDITOR # set the local branch using NEW_EDITOR as git editor

因此,工具需要修改git编辑器并处理git-rebase-todo文件。

#!/usr/bin/env python3
#encoding: UTF-8

import os
import sys

def change_editor(current_file):
    os.system("git config --local --replace-all  core.editor " + current_file) # Set current_file as git editor
    os.system("git rebase -i") # execute the "git rebase -i" and will invoke the python file later with git-rebase-todo file as argument
    os.system("git config --local --replace-all core.editor vim") # after work reset the git editor to default

def rebase_commits(todo_file):
    with open(todo_file, "r+") as f:
        contents = f.read() # read git-rebase-todo's content
        contents = contents.split("\n")
        first_commit = True
        f.truncate()
        f.seek(0)
        for content in contents:
            if content.startswith("pick"):
                if first_commit:
                    first_commit = False
                else:
                    content = content.replace("pick", "squash") # replace the pick to squash except for the first pick
            f.write(content + "\n")

def main(args):
    if len(args) == 2:
        rebase_commits(args[1]) # process the git-rebase-todo
    else:
        change_editor(os.path.abspath(args[0])) # set git editor

if __name__ == "__main__":
    main(sys.argv)

参考:https://liwugang.github.io/2019/12/30/git_commits_en.html

ukqbszuj

ukqbszuj7#

其他的答案可能是正确的。但是这里有一个简单的解决方案,我用了很多次,效果很好。

    • 情况**:我们在特性分支中创建了多个提交(可能是一些命中和尝试)。现在,在向master/main分支发出最终的拉/合并请求之前,我们希望将所有提交合并到一个提交中,并在最新master/main分支的顶部添加更新的有用提交消息。

步骤:1

go to the feature branch where you want to perform this action ( Better to make backup branch before proceed )

步骤:2

git reset --soft origin/main

步骤:3(可选,仅显示状态)

git status

步骤:4

git commit -m "New updated and Final commit msg"

相关问题