Use Merge and Rebase in Git to synchronize code with open-source projects, gitrebase
There are two main working modes for open-source project-based development. Mode 1 is to pull a branch from an open-source project, develop a new feature in this branch, and merge it into upstream. Applicable to developers who are open-source projects. Mode 2 develops independently after pulling branches from open-source projects, but regularly pulls updates from upstream (for example, when important versions are upgraded ). Either way, the local branch and upstream synchronization code problems will occur. To this end, git provides two methods: merge and rebase. The following is a simple example of their basic processes.
Assume that the git address of the open-source project is git: // xxx.org/xxx/project. Previously, code was pulled from it and put as git repository on the Local Code Management Server (such as the gerrit server ). On the local development machine, there is a local server to clone the git of this project. As a result, running git remote-v on a local development machine would result in something similar to: local ssh: // jzj@gerrit3.company.com: xxxxx/xxx/project (fetch) local ssh: // jzj@gerrit3.company.com: xxxxx/xxx/project (push)
First, add the open-source project git to the remote source list. The name is tentatively set to upstream. $ Git remote add upstream git: // pull git fetch and the result of git remote-v becomes: upstream git: // xxx.org/xxx/project (fetch) upstream git: // xxx.org/xxx/project (push) local ssh: // jzj@gerrit3.company.com: xxxxx/xxx/project (fetch) local ssh: // jzj@gerrit3.company.com: xxxxx/xxx/project (push) now git has been associated with two sources.
Next, create a branch from the upstream source, called upstream, which is consistent with the Code in git of the open-source project: $ git checkout remotes/upstream/master-B upstream assume that git log is: commit 2 from branch upstream 2015/1/3 Commit 1 from branch upstream 2015/1/1
Pull the branch from the local source, which is called a topic. It contains local changes (such as the new feature): $ git checkout remotes/local/master-B topic. Of course, if you want to submit it to the gerrit server in the future, use repo start topic here .. Assume that the log is: Commit 1 from branch topic 2015/1/2
Merge ModeMerge the commit that branch A does not have on branch B into A commit, and then attach it to branch B. If you want the topic branch to synchronize changes in upstream, run the following command: $ git checkout topic $ git merge upstream. If you want upstream to synchronize topic changes, replace the positions of the branch names in the preceding command. If there is a conflict, it will let you solve it (view the conflict through git diff). After the conflict is solved, git add + git commit (or git commit-). The log displayed in the git log of the topic branch is similar to the following: merge branch 'upstream' into topicCommit 2 from branch upstream 2015/1/3 Commit 1 from branch topic 2015/1/2 Commit 1 from branch upstream 2015/1/1 commit in chronological order, the top commit represents the bundle commit of merge. If git reset is removed, all changes synchronized on the original upstream will disappear.
Rebase MethodIt is to repeat the commit that branch A does not have on branch B one by one on branch B. The git rebase document shows that if it is git rebase upstream topic, it is equivalent to git checkout topic + git rebase upstream. That is, repeat the commit on the topic branch with the upstream HEAD as the base. Duplicate commit will be automatically ignored. Therefore, use git rebase topic upstream if Mode 1 is mentioned earlier, and use git rebase upstream topic if Mode 2 is used. Generally, the -- ignore-whitespace parameter $ git rebase upstream topic -- ignore-whitespace is added to avoid whitespace errors. For more fine-grained rebase control, see-I parameters.
Conflicts may occur during the rebase process. When a conflict occurs, use git diff to check the conflict. For example, if it is a. c, execute $ git add a. c after resolving the conflict and then execute the following command to continue the cheerful rebase: $ git rebase -- continue
The git log of the topic branch is similar to the following: Commit 1 from branch topic 2015/1/2 Commit 2 from branch upstream 2015/1/3 Commit 1 from branch upstream 2015/1/1, this is not in chronological order. The commit of the topic branch is above, while the commit of upstream is below. If it is git rebase topic upstream, the order is the opposite. Finally, if you want the upstream branch to synchronize the code of the topic branch. You can go to the upstream branch to perform a fast-forward merge: $ git checkout upstream $ git merge topic.
After synchronization, the git push is git push, the repo upload is repo upload, And the synchronized code is updated to the local code management server.
To sum up, the biggest difference between merge and rebase is that the former uses all the commit to be played to the target branch as a whole commit, the latter is replayed one by one (but note that <SHA1> is different after it is played, that is, although the content is the same, the commit is no longer the original one ). From the results, the commit in the Post-merge log is chronological, and the most recent commit records this merge operation. In the post-rebase log, the commit of one branch is not in chronological order, but after the commit of another branch. In general, rebase is more flexible and powerful than merge. But its disadvantage is that it will rewrite history. Therefore, do not rebase the public branch. Otherwise, you may be at risk of being hacked by a colleague (because he may have made changes based on the history before rewriting ). The basic principle is to use rebase when synchronizing code from the remote end to the local end. Merge is used when the local feature development is completed and the synchronization is back to the remote end.