首页 文章

`git merge`和`git merge --no-ff`有什么区别?

提问于
浏览
694

使用 gitk log ,我无法发现两者之间的差异 . 如何观察差异(使用git命令或某些工具)?

5 回答

  • 779

    如果 --no-ff 标志检测到您当前的 HEAD 是您尝试合并的提交的祖先,则 --no-ff 标志会阻止 git merge 执行"fast-forward" . 快进是指git只是将您的分支指针移动到指向传入提交的位置,而不是构建合并提交 . 这通常发生在没有任何本地更改的情况下执行 git pull .

    但是,有时您希望防止此行为发生,通常是因为您希望维护特定的分支拓扑(例如,您正在合并主题分支,并且您希望确保在阅读历史记录时看起来如此) . 为此,您可以传递 --no-ff 标志, git merge 将始终构建合并而不是快进 .

    同样,如果要执行 git pull 或使用 git merge 以显式快进,并且如果它无法快进则要保释,则可以使用 --ff-only 标志 . 通过这种方式,您可以不经思考地定期执行 git pull --ff-only 之类的操作,然后如果错误输出,您可以返回并决定是否要合并或重新绑定 .

  • 23

    这个问题的图解答案

    Here is a site有使用git merge --no-ff的清晰解释和图解说明:

    difference between git merge --no-ff and git merge

    直到我看到这个,我完全迷失了git . 使用--no-ff可以让某些人清楚地查看历史记录see the branch you checked out . (该链接指向github的"network"可视化工具)这里是带有插图的another great reference . 这个参考文章很好地补充了第一个,更多地关注那些不熟悉git的人 .


    像我这样的新手的基本信息

    如果你像我一样,而不是Git-guru,my answer here描述了处理从git跟踪中删除文件而不从本地文件系统中删除文件,这似乎记录不清,但经常发生 . 另一个新情况是getting current code,仍然设法逃避我 .


    示例工作流程

    我将一个软件包更新到我的网站,不得不回到我的笔记中查看我的工作流程;我认为在这个答案中添加一个例子很有用 .

    我的git命令工作流程:

    git checkout -b contact-form
    (do your work on "contact-form")
    git status
    git commit -am  "updated form in contact module"
    git checkout master
    git merge --no-ff contact-form
    git branch -d contact-form
    git push origin master
    

    Below: 实际用法,包括解释 .
    注意:下面的输出是剪切的; git非常冗长 .

    $ git status
    # On branch master
    # Changed but not updated:
    #   (use "git add/rm <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #       modified:   ecc/Desktop.php
    #       modified:   ecc/Mobile.php
    #       deleted:    ecc/ecc-config.php
    #       modified:   ecc/readme.txt
    #       modified:   ecc/test.php
    #       deleted:    passthru-adapter.igs
    #       deleted:    shop/mickey/index.php
    #
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       ecc/upgrade.php
    #       ecc/webgility-config.php
    #       ecc/webgility-config.php.bak
    #       ecc/webgility-magento.php
    

    请注意上面的3件事:
    1)在输出中,您可以看到ECC包升级的更改,包括添加新文件 .
    2)另请注意,我删除了两个独立于此更改的文件(不在 /ecc 文件夹中) . 我不会将这些文件删除与 ecc 混淆,而是稍后会使用不同的 cleanup 分支来反映这些文件的删除 .
    3)我没有按照我的工作流程!当我试图让ecc再次工作时,我忘记了git .

    下面:而不是我通常会做的全包 git commit -am "updated ecc package" ,我只想在 /ecc 文件夹中添加文件 . 那些删除的文件并不是我的 git add 的特定部分,但因为它们已经在git中被跟踪,我需要从这个分支的提交中删除它们:

    $ git checkout -b ecc
    $ git add ecc/*
    $ git reset HEAD passthru-adapter.igs
    $ git reset HEAD shop/mickey/index.php
    Unstaged changes after reset:
    M       passthru-adapter.igs
    M       shop/mickey/index.php
    
    $ git commit -m "Webgility ecc desktop connector files; integrates with Quickbooks"
    
    $ git checkout master
    D       passthru-adapter.igs
    D       shop/mickey/index.php
    Switched to branch 'master'
    $ git merge --no-ff ecc
    $ git branch -d ecc
    Deleted branch ecc (was 98269a2).
    $ git push origin master
    Counting objects: 22, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (14/14), done.
    Writing objects: 100% (14/14), 59.00 KiB, done.
    Total 14 (delta 10), reused 0 (delta 0)
    To git@github.com:me/mywebsite.git
       8a0d9ec..333eff5  master -> master
    

    用于自动执行上述操作的脚本

    在一天中使用了这个过程10次之后,我已经开始编写批处理脚本来执行命令,所以我做了一个几乎适当的 git_update.sh <branch> <"commit message"> 脚本来执行上述步骤 . Here is the Gist source为该脚本 .

    而不是 git commit -am 我选择通过 git status 生成的"modified"列表中的文件,然后粘贴此脚本中的文件 . 这是因为我做了几十次编辑,但想要不同的分支名称来帮助分组更改 .

  • 33

    --no-ff 选项确保不会发生快进合并,并确保 a new commit object will always be created . 如果您希望git维护功能分支的历史记录,这可能是理想的 .
    git merge --no-ff vs git merge
    在上图中,左侧是使用 git merge --no-ff 后的git历史记录的示例,右侧是使用 git merge 的示例,其中可以进行ff合并 .

    EDIT :此映像的先前版本仅指示合并提交的单个父级 . Merge commits have multiple parent commits git用于维护"feature branch"和原始分支的历史记录 . 多个父链接以绿色突出显示 .

  • 794

    这是一个老问题,这在其他帖子中有点巧妙地提到,但是让我这次点击的解释是 non fast forward merges will require a separate commit .

  • 164

    Merge Strategies

    • 显式,非快进合并

    • 隐式通过rebase或快进合并

    • 压缩合并

    enter image description here

    enter image description here

    enter image description here

    enter image description here

相关问题