Create and merge branches
- In git, each commit is connected into a timeline, which is a branch. (After we initialize a directory, the master branch is generated after the default commit, which is called the master branch ). In git, HEAD is used to point to the current branch, and the master pointer (or your newly created dev branch, etc.) is used to point to the most recent commit. In this way, we can know the current branch and the latest commit point of the current branch
- Next, enter the test: first create the branch dev ( git creates a dev pointer, and then points to the latest commit ), then switch the branch to dev (the HEAD pointer points to the dev branch ). So git creating a branch is as simple as adding a dev pointer, then changing the pointer of HEAD and it's done. This is why git compares ( ఠൠఠ )ノ
$ git checkout -b dev Switched to a new branch 'dev'
or
$ git branch * dev master
- Now, we can work on the dev branch. After the commit is submitted, the dev pointer moves one step forward, while the master pointer is still in place
$ cat >> doc1.txt add a new branch named dev $ git add doc1.txt $ git commit -m "branch dev test" [dev b796f15] branch dev test 1 file changed, 1 insertion(+)
- When the task of the dev branch is processed, switch back to the master branch, but at this time because the master pointer is still in place, the doc1 file has no content added to the dev
$ git checkout master Switched to branch 'master' Your branch is up-to-date with 't3/master'. $ cat doc1.txt this is 1 line this is 5 line this is 7 line
- So how to synchronize the changes on the dev branch to the master branch? Git directly points the master pointer to the commit pointed to by the dev pointer , so that the merge is completed, but the point of the lower pointer is changed, and the content of the workspace is not modified.
$ git merge dev Updating feed81d..b796f15 Fast-forward doc1.txt | 1 + 1 file changed, 1 insertion(+) $ cat doc1.txt this is 1 line this is 5 line this is 7 line add a new branch named dev
Finally, you can delete the dev branch.
$ git branch -d dev Deleted branch dev (was b796f15). $ git branch * master
Merge conflicting branches
When the branch was merged above, the commit was not made on the main branch, and then the merge was merged, so everything went smoothly. However, if you commit on the new branch you created, and then revise and commit on the main branch ( note: if there is no modification, direct add--->commit will not cause a merge conflict. Because you have not modified the content, also There is no content to add to the temporary storage area. Of course, if you commit at this time, the master pointer will not move forward. )
- Next, let's demonstrate with an example, first modify and submit on the tre branch
$ cat >> doc1.txt this is new house $ git checkout -b tre Switched to a new branch 'tre' M doc1.txt $ git add doc1.txt $ git commit -m "tre" [tre 9d53879] tre 1 file changed, 1 insertion(+)
- Then modify and commit on the master branch
$ git checkout master Switched to branch 'master' Your branch is up-to-date with 't3/master'. $ cat doc1.txt this is 1 line this is 5 line this is 7 line $ cat >> doc1.txt this is old house $ git add doc1.txt $ git commit -m "mas" [master a684d34] mas 1 file changed, 1 insertion(+)
- final merge
$ git goes tre Auto-merging doc1.txt CONFLICT (content): Merge conflict in doc1.txt Automatic merge failed; fix conflicts and then commit the result.
I found that the error was reported, and the structure tree at this time is like this
You can also see the error with the omnipotent git status view.
$ git status On branch master Your branch is ahead of 't3/master' by 1 commit. (use "git push" to publish your local commits) You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: doc1.txt no changes added to commit (use "git add" and/or "git commit -a")
If you view the doc1 file directly
$ cat doc1.txt this is 1 line this is 5 line this is 7 line <<<<<<< HEAD this is old house ======= this is new house >>>>>>> tre
From the doc1 file, we can see the modifications on the master branch and the tre branch, so we can manually modify it to this is maybe old or new house and submit it, the structure tree at this time is like this
$ vim doc1.txt $ cat doc1.txt this is 1 line this is 5 line this is 7 line this is maybe old or new house $ git add doc1.txt $ git commit -m "handle conflict" [master cbf3047] handle conflict
You can also view the commit structure through git log --graph --pretty=oneline --abbrev-commit
$ git log --graph --pretty=oneline --abbrev-commit * cbf3047 (HEAD -> master) handle conflict |\ | * 9d53879 (three) three * | a684d34 but |/ * 50e1e19 (t3/master) 1
Branch management strategy
When merging branches above, the Fast forward mode is used for merging. Although this mode is efficient, the disadvantage is that if the branch is deleted, the branch information will be lost.
If Fast forward mode is disabled when merging, a new commit will be generated when merging, and the branch information can be known from the branch history information
Example demonstration:
Modify data on branch dev and commit
$ git init Initialized empty Git repository in /data/project/lh/testgit/git4/.git/ $ cat >> doc 1 $ git add doc $ git commit -m "m 1" [master (root-commit) ec0e911] m 1 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 doc $ git checkout -b dev Switched to a new branch 'dev' $ cat >> doc dev 1 $ git add doc $ git commit -m "dev 1" [dev 0564329] dev 1 1 files changed, 1 insertions(+), 0 deletions(-)
Then switch to the master branch ( be sure to switch to the master branch ) and commit with --no-ff . You can see the specific commit information of the branch history tree
$ git checkout master Switched to branch 'master' $ git merge --no-ff -m "--no-ff merge dev" dev Merge made by recursive. doc | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) $ git log --graph --pretty=oneline --abbrev-commit * c61833a --no-ff merge dev |\ | * b9eabc6 dev 1 |/ * b127f76 m 1
At this time, if you commit the dev branch again, then merge to the master branch. At this point, whether you add the --no-ff parameter or not, the branch history tree can display specific commit information.
$ cat >> doc dev2 $ git add doc $ git commit -m "dev 2" [dev e655732] dev 2 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout master Switched to branch 'master' [lh@super git4]$ git merge dev Merge made by recursive. doc | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) [lh@super git4]$ git log --graph --pretty=oneline --abbrev-commit * 579bfd8 Merge branch 'dev' |\ | * e655732 dev 2 * | c61833a --no-ff merge dev |\ \ | |/ | * b9eabc6 dev 1 |/ * b127f76 m 1