As we saw in the previous section, when many people collaborate on the same branch, conflicts can easily arise. Even if there is no conflict, the children's shoes of post-push have to pull first, merge locally, and then push succeeds.
After each merge and push, the branch becomes as follows:
$ git log --graph --pretty=oneline --abbrev-commit * d1be385 (HEAD -> master, origin/master) init hello * e5e69f1 Merge branch 'dev' |\ | * 57c53ab (origin/dev, dev) fix env conflict | |\ | | * 7a5e5dd add env | * | 7bd91f1 add new env | |/ * | 12a631b merged bug fix 101 |\ \ | * | 4c805e2 fix bug 101 |/ / * | e1e9c68 merge with no-ff |\ \ | |/ | * f52c633 add merge |/ * cf810e4 conflict fixed
All in all, it looks chaotic. Children's shoes with obsessive-compulsive disorder ask: Why can't Git's submission history be a clean straight line?
In fact, it can be done!
Git has an operation called rebase, which has been translated as "radical change".
Don't imagine at will. Let's start with practical problems and see how to turn the bifurcation submission into a straight line.
After synchronizing with the remote branch, we made two submissions to the file hello.py. Use the git log command to see:
$ git log --graph --pretty=oneline --abbrev-commit * 582d922 (HEAD -> master) add author * 8875536 add comment * d1be385 (origin/master) init hello * e5e69f1 Merge branch 'dev' |\ | * 57c53ab (origin/dev, dev) fix env conflict | |\ | | * 7a5e5dd add env | * | 7bd91f1 add new env ...
Note that Git uses (HEAD - > master) and (origin/master) to identify the HEAD of the current branch and the location of the remote origin are 582d922 add author and d1be385 init hello, respectively. Local branches submit two faster than remote branches.
Now let's try to push the local branch:
$ git push origin master To github.com:michaelliao/learngit.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'git@github.com:michaelliao/learngit.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Unfortunately, it failed, which means someone pushed the remote branch ahead of us. According to experience, first pull:
$ git pull remote: Counting objects: 3, done. remote: Compressing objects: 100% (1/1), done. remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0 Unpacking objects: 100% (3/3), done. From github.com:michaelliao/learngit d1be385..f005ed4 master -> origin/master * [new tag] v1.0 -> v1.0 Auto-merging hello.py Merge made by the 'recursive' strategy. hello.py | 1 + 1 file changed, 1 insertion(+)
Then use git status to see the status:
$ git status On branch master Your branch is ahead of 'origin/master' by 3 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean
With the merged submissions, our local branch is now three submissions ahead of the remote branch.
Use git log to see:
$ git log --graph --pretty=oneline --abbrev-commit * e0ea545 (HEAD -> master) Merge branch 'master' of github.com:michaelliao/learngit |\ | * f005ed4 (origin/master) set exit=1 * | 582d922 add author * | 8875536 add comment |/ * d1be385 init hello ...
For children with obsessive-compulsive disorder shoes, things are not right now, submitting a bifurcation of history. If you push the local branch to remote now, is there any problem?
Yes!
What's the problem?
Disgraceful!
Is there a solution?
Yes!
At this point, rebase comes in handy. Let's try the command git rebase:
$ git rebase First, rewinding head to replay your work on top of it... Applying: add comment Using index info to reconstruct a base tree... M hello.py Falling back to patching base and 3-way merge... Auto-merging hello.py Applying: add author Using index info to reconstruct a base tree... M hello.py Falling back to patching base and 3-way merge... Auto-merging hello.py
Output a lot of operations, what is the effect? Then use git log to see:
$ git log --graph --pretty=oneline --abbrev-commit * 7e61ed4 (HEAD -> master) add author * 3611cfe add comment * f005ed4 (origin/master) set exit=1 * d1be385 init hello ...
The original bifurcated submission now becomes a straight line! How does this magic work? In fact, the principle is very simple. We noticed that Git "moved" our local submission to f005ed4 (origin/master) set exit=1, so that the entire submission history became a straight line. Before and after rebase operation, the final submission content is the same, but our local commit modification content has changed. Their modification is no longer based on d1be385 init hello, but on f005ed4 (origin/master) set exit=1, but the final submission 7e61ed4 content is the same.
This is the characteristic of rebase operation: it is more intuitive to "organize" the bifurcated submission history into a straight line. The disadvantage is that the local bifurcation submission has been modified.
Finally, the local branch is pushed to the remote through the push operation:
Mac:~/learngit michael$ git push origin master Counting objects: 6, done. Delta compression using up to 4 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (6/6), 576 bytes | 576.00 KiB/s, done. Total 6 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), completed with 1 local object. To github.com:michaelliao/learngit.git f005ed4..7e61ed4 master -> master
Then use git log to see the effect:
$ git log --graph --pretty=oneline --abbrev-commit * 7e61ed4 (HEAD -> master, origin/master) add author * 3611cfe add comment * f005ed4 set exit=1 * d1be385 init hello ...
The submission history of remote branches is also a straight line.
Summary
-
The rebase operation can organize the local unplugged bifurcation submission history into straight lines.
-
The purpose of rebase is to make it easier for us to view changes in historical submissions, because bifurcated submissions require tripartite comparisons.