git merge简介【转】

转自:http://blog.csdn.net/hudashi/article/details/7664382

git merge的基本用法为把一个分支或或某个commit的修改合并现在的分支上。
我们可以运行git merge -h和git merge --help查看其命令,后者会直接转到一个网页(git的帮助文档),更详细。
usage: git merge [options] [<commit>...]
   or: git merge [options] <msg> HEAD <commit>
   or: git merge --abort

    -n                    do not show a diffstat at the end of the merge
    --stat                show a diffstat at the end of the merge
    --summary             (synonym to --stat)
    --log[=<n>]           add (at most <n>) entries from shortlog to merge commi                                                                                                                t message
    --squash              create a single commit instead of doing a merge
    --commit              perform a commit if the merge succeeds (default)
    -e, --edit            edit message before committing
    --ff                  allow fast-forward (default)
    --ff-only             abort if fast-forward is not possible
    --rerere-autoupdate   update the index with reused conflict resolution if po                                                                                                                ssible
    -s, --strategy <strategy>
                          merge strategy to use
    -X, --strategy-option <option=value>
                          option for selected merge strategy
    -m, --message <message>
                          merge commit message (for a non-fast-forward merge)
    -v, --verbose         be more verbose
    -q, --quiet           be more quiet
    --abort               abort the current in-progress merge
    --progress            force progress reporting
    -S, --gpg-sign[=<key id>]
                          GPG sign commit
    --overwrite-ignore    update ignored files (default)
git merge [options] <msg> HEAD <commit> 这里的 HEAD 其实就是分支名,用于说明把 HEAD  分支合并到当前分支。

--squash选项的含义是:本地文件内容与不使用该选项的合并结果相同,但是不保留待合并分支上的历史信息,也不提交、不移动HEAD,因此需要一条额外的commit命令。其效果相当于将another分支上的多个commit合并成一个,放在当前分支上,原来的commit历史则没有拿过来。

   判断是否使用--squash选项最根本的标准是,待合并分支上的历史是否有意义。

如果在开发分支上提交非常随意,甚至写成微博体,那么一定要使用--squash选项。版本历史记录的应该是代码的发展,而不是开发者在编码时的活动。

只有在开发分支上每个commit都有其独自存在的意义,并且能够编译通过的情况下(能够通过测试就更完美了),才应该选择缺省的合并方式来保留commit历史。

--no-ff 

Create a merge commit even when the merge resolves as a fast-forward. This is the default behaviour when merging an annotated (and possibly signed) tag. 

我们在将Develop分支发布到Master分支时,可能采用如下的命令:

  # 切换到Master分支

  git checkout master

  # 对Develop分支进行合并

  git merge --no-ff develop

这里稍微解释一下,上一条命令的--no-ff参数是什么意思。

这个命令要通过git merge --help查看其命令,后者会直接转到一个网页,才能看到其详细说明

默认情况下,Git执行"快进式合并"(fast-farward merge),会直接将Master分支指向Develop分支。

示图1-1

 

示图1-2

命令:

git checkout master

git merge robin_local

 使用--no-ff参数后,会执行正常合并,在Master分支上生成一个新节点。为了保证版本演进的清晰,我们希望采用这种做法。关于合并的更多解释,请参考Benjamin Sandofsky的《Understanding the Git Workflow》。

示图2-1

 

示图2-2

命令:

git checkout master

git merge robin_local

 

图3

 

以下是一篇来自于哈佛大学关于git merge的文章

英文地址:http://www.eecs.harvard.edu/~cduan/technical/git/git-3.shtml 

Merging

After you have finished implementing a new feature on a branch, you want to bring that new feature into the main branch, so that everyone can use it. You can do so with the git merge or git pull command.

The syntax for the commands is as follows:

git merge [head] 
git pull . [head] 

They are identical in result. (Though the merge form seems simpler for now, the reason for the pull form will become apparent when discussing multiple developers.)

These commands perform the following operations. Let the current head be called current, and the head to be merged calledmerge.

  1. Identify the common ancestor of current and merge. Call it ancestor-commit.
  2. Deal with the easy cases. If the ancestor-commit equals merge, then do nothing. If ancestor-commit equals current, then do a fast forward merge.
  3. Otherwise, determine the changes between the ancestor-commit and merge.
  4. Attempt to merge those changes into the files in current.
  5. If there were no conflicts, create a new commit, with two parents, current and merge. Set current (and HEAD) to point to this new commit, and update the working files for the project accordingly.
  6. If there was a conflict, insert appropriate conflict markers and inform the user. No commit is created.

Important note: Git can get very confused if there are uncommitted changes in the files when you ask it to perform a merge. So make sure to commit whatever changes you have made so far before you merge.

So, to complete the above example, say you check out the master head again and finish writing up the new data for your paper. Now you want to bring in those changes you made to the headers.

The repository looks like this:

 

         +---------- (D)

        /             |

(A) -- (B) -- (C) -------------- (E)

                      |           |

                 fix-headers    master

                                  |

                                 HEAD

where (E) is the commit reflecting the completed version with the new data.

You would run:

 

 

git merge fix-headers

If there are no conflicts, the resulting respository looks like this:

 

         +---------- (D) ---------------+

        /             |                  \

(A) -- (B) -- (C) -------------- (E) -- (F)

                      |                  |

                 fix-headers           master

                                         |

                                        HEAD

The merge commit is (F), having parents (D) and (E). Because (B) is the common ancestor between (D) and (E), the files in (F) should contain the changes between (B) and (D), namely the heading fixes, incorporated into the files from (E).

Note on terminology: When I say “merge head A into head B,” I mean that head B is the current head, and you are drawing changes from head A into it. Head B gets updated; nothing is done to head A. (If you replace the word “merge” with the word “pull,” it may make more sense.)

Resolving Conflicts

A conflict arises if the commit to be merged in has a change in one place, and the current commit has a change in the same place. Git has no way of telling which change should take precedence.

To resolve the commit, edit the files to fix the conflicting changes. Then run git add to add the resolved files, and rungit commit to commit the repaired merge. Git remembers that you were in the middle of a merge, so it sets the parents of the commit correctly.

 

如果没有冲突的话,merge完成。有冲突的话,git会提示那个文件中有冲突,比如有如下冲突:

<<<<<<< HEAD:test.c

printf (“test1″);

=======

printf (“test2″);

>>>>>>> issueFix:test.c

可以看到 ======= 隔开的上半部分,是 HEAD(即 master 分支,在运行 merge 命令时检出的分支)中的内容,下半部分是在 issueFix 分支中的内容。解决冲突的办法无非是二者选其一或者由你亲自整合到一起。比如你可以通过把这段内容替换为下面这样来解决:

printf (“test2″);

这个解决方案各采纳了两个分支中的一部分内容,而且删除了 <<<<<<<,=======,和>>>>>>> 这些行。

在解决了所有文件里的所有冲突后,运行git add 将把它们标记为已解决(resolved)。

然后使用git commit命令进行提交,merge就算完成了

Fast Forward Merges

A fast forward merge is a simple optimization for merging. Say your repository looks like this:

 

            +-- (D) ------ (E)

               /            |

(A) -- (B) -- (C)           |

               |            |

            current     to-merge

               |

              HEAD

and you run git merge to-merge. In this case, all Git needs to do is set current to point to (E). Since (C) is the common ancestor, there are no changes to actually “merge.”

Hence, the resulting merged repository looks like:

 

                +-- (D) -- (E)

               /            |

(A) -- (B) -- (C)           |

                            |

                    to-merge, current

                                 |

                                HEAD

That is, to-merge and current both point to commit (E), and HEAD still points to current.

Note an important difference: no new commit object is created for the merge. Git only shifts the head pointers around.

Common Merge Use Patterns

There are two common reasons to merge two branches. The first, as explained above, is to draw the changes from a new feature branch into the main branch.

The second use pattern is to draw the main branch into a feature branch you are developing. This keeps the feature branch up to date with the latest bug fixes and new features added to the main branch. Doing this regularly reduces the risk of creating a conflict when you merge your feature into the main branch.

One disadvantage of doing the above is that your feature branch will end up with a lot of merge commits. An alternative that solves this problem is rebasing, although that comes with problems of its own.

时间: 2024-09-20 12:41:33

git merge简介【转】的相关文章

git merge简介(转)

git merge的基本用法为把一个分支或或某个commit的修改合并现在的分支上.我们可以运行git merge -h和git merge --help查看其命令,后者会直接转到一个网页(git的帮助文档),更详细.usage: git merge [options] [<commit>...]   or: git merge [options] <msg> HEAD <commit>   or: git merge --abort     -n           

聊下git merge --squash

你经常会面临着将dev分支或者很多零散的分支merge到一个公共release分支里. 但是有一种情况是需要你处理的,就是在你的dev的分支里有很多commit记录.而这些commit是无需在release里体现的. develop 主分支 develop主分支最近的一个commit是"fix imageprint bug.".我们拉出一个分支进行项目开发,里面会有很多commit记录. git checkout -b develop_newfeature_ImportDataInte

Merge和Rebase在Git中的区别

git命令Merge和Rebase的区别 git merge 会生成一个新得合并节点,而rebase不会 比如:       D---E test        /   A---B---C---F master   使用merge合并:       D--------E        /          \   A---B---C---F----G   test, master   而使用rebase则: A---B---D---E---C'---F'   test, master     使

git fetch, merge, pull, push需要注意的地方(转)

在git操作中,我们经常会用到fetch, merge, pull和push等命令,以下是一些我们需要注意的地方. 给大家准备了参考资料: 1. Whatʼs a Fast Forward Merge?:https://sandofsky.com/images/fast_forward.pdf 2. Understanding the Git Workflow:https://sandofsky.com/blog/git-workflow.html 3. Understanding Git: M

Git 少用 Pull 多用 Fetch 和 Merge(转)

英文原文:git: fetch and merge, don't pull This is too long and rambling, but to steal a joke from Mark Twain Blaise Pascal I haven't had time to make it shorter yet.  There is some discussion of this post on the git mailing list, but much of it is tangen

git pull VS git fetch&amp;merge(good)

从图中可以看到,git fetch和git pull的区别, git fetch 不会自动的将结果merge到本地,只是将远程版本同步到本地版本库,而不会merge到本地副本. git pull  将会直接把working directory中的内容覆盖掉. 使用git fetch和git pull都可以更新远程仓库的代码到本地,但是它们之间还是有区别. git fetch  1 git fetch origin master 2 git log -p master..origin/master

研发团队GIT开发流程新人学习指南

本文定位于为使用GIT标准分支开发流程的开发团队新人提供一份参考指南,其中的内容都是我们公司在研发团队初创时所遵循的一些开发流程标准,经过近一年的实践,虽说还有很多不足,但是随着团队经验的丰富和人员的扩张,我会适时地更新本文,分享我们在使用GIT开发流程中遇到的问题和解决方案. 本文将会持续修正和更新,最新内容请参考我的 GITHUB 上的 程序猿成长计划 项目,欢迎 Star,更多精彩内容请 follow me. 分支流程说明 简介 项目中长期存在的两个分支 master:主分支,负责记录上线

Git &amp; Github 一页简明笔记(转)main

由于小组工程需要使用git&github的版本控制来协作,但我对其使用并不熟悉,特此写篇一页的笔记放在手边,备随时查阅. 使用方法:常用命令供随时查阅,其余内容供新手了解.   0. 常用命令一览 # 配置仓库命令(项目名:play,项目发起者的名字:icedream61,URL=get@github.com:icedream61/play.git) git clone URL # 第一次克隆远程仓库,并关联:远程仓库 -> 本地仓库 git remote add origin URL #

Git详解之五:分布式Git

原文链接:http://blog.jobbole.com/25660/ 原文:<Pro Git> 为了便于项目中的所有开发者分享代码,我们准备好了一台服务器存放远程 Git 仓库.经过前面几章的学习,我们已经学会了一些基本的本地工作流程中所需用到的命令.接下来,我们要学习下如何利用 Git 来组织和完成分布式工作流程.(伯乐在线注:如果你对Git还不了解,建议从本Git系列第一篇文章开始阅读) 特别是,当作为项目贡献者时,我们该怎么做才能方便维护者采纳更新:或者作为项目维护者时,又该怎样有效管