Git branch management: resolving conflicts
Introduce conflict
When two changes are merged into the same branch and interfere with each other, merge conflicts.
Next, we create two branches and run them in parallel, artificially creating merge conflicts. First, we create two new branches test/conflict1 and test/conflict2 from the main branch of the git_test project
$ git branch test/conflict1
$ git branch test/conflict2
Now we switch to test/conflict1
$ git checkout test/conflict1
Switched to branch 'test/conflict1'
$ git branch
main
master
* test/conflict1
test/conflict2
We added a new sentence I'm used to merging branches with git merge. in example.txt, now the example.txt of the test/conflict1 branch looks like this:
Hello, Git!
Learning git branch knowledge.
I'm used to merging branches with git merge.
Then we commit the test/conflict1 branch.
Next, switch to the test/conflict2 branch, and also change example.txt (when you just switched to the test/conflict2 branch, the example.txt here is still the same as the example.txt of the main branch). Let's add another sentence to the file, now the example.txt of the test/conflict2 branch is as follows:
Hello, Git!
Learning git branch knowledge.
I love using git rebase, it works well.
Similarly, we push the test/conflict2 branch to the remote database.
Now, our branch situation looks like this

Let's merge test/conflict1 into main first, because now there is no change in main, merge test/conflict1 in fast-forward mode in the past, we can easily merge it into main
$ git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
$ git merge test/conflict1
Updating 9b83394..949f645
Fast-forward
example.txt | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
$ git push
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/FelixWuu/git_test
9b83394..949f645 main -> main
$ git branch -d test/conflict1
Deleted branch test/conflict1 (was 949f645).
Then, we merge test/conflict2 into the main branch
$ git branch
* main
master
test/conflict2
$ git merge test/conflict2
Auto-merging example.txt
CONFLICT (content): Merge conflict in example.txt
Automatic merge failed; fix conflicts and then commit the result.
We can see that this merge was conflicting, we made different changes under the same file. Git tries to resolve conflicts automatically, but fails to resolve conflicts, it prompts Automatic merge failed; fix conflicts and then commit the result. Git fails to automatically merge, and we need to fix conflicts manually before committing.
conflict resolution
Since the test/conflict1 branch was merged before main, the latest features are now in the main branch, and the latest commit of the main branch is the red circle in the figure below

The features in test/conflict2 will affect the features of the main branch, and their differences conflict. Let's open the example.txt file of the main branch now to see
Hello, Git!
Learning git branch knowledge.
<<<<<<< HEAD
I'm used to merging branches with git merge.
=======
I love using git rebase, it works well.
>>>>>>> test/conflict2
Lines 5 to 9 are where the conflict is. The current branch above ======= has sentences, and below is the merged sentence from test/conflict2. We need to choose the changes here.
We choose to keep both, and just delete the things we don't need.
Hello, Git!
Learning git branch knowledge.
I'm used to merging branches with git merge.
I love using git rebase, it works well.
If you use a code editor, such as vscode, etc., the conflicts here will also intelligently provide buttons for you to choose whether to keep the features of the original branch, the newly merged features, or both.
Now we have modified the file and resubmit it.
$ git status
On branch main
Your branch is up to date with 'origin/main'.
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: example.txt
$ git add .
$ git commit -m "fix: resolve conflicts"
[main c970aea] fix: resolve conflicts
$ git push
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 449 bytes | 449.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/FelixWuu/git_test
949f645..c970aea main -> main
$ git branch -d test/conflict2
Deleted branch test/conflict2 (was 6f30a3f).
Now, the git branch looks like the image below

You can also delete remote branches on the web


Merge with rebase
Let's do the conflict introduced above again and create two branches from main. Add a new line of content to the example.txt file on two different branches, and merge one of the branches test/conflict3 first
$ git branch test/conflict3
$ git branch test/conflict4
$ git checkout test/conflict3
Switched to branch 'test/conflict3'
-- Revise example.txt, Then submit it, just skip it and don't post it --
$ git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
$ git merge test/conflict3
Updating c970aea..ad478ee
Fast-forward
example.txt | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
$ git push
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/FelixWuu/git_test
c970aea..ad478ee main -> main
Now we modify test/conflict4
$ git rebase master
After that, the operation is the same as that of merge, and then we use the merge command git merge test/conflict4, and we can see that it has become Fast-forward mode.
Let's talk about merge again
git merge merges multiple commit sequences into a unified commit history. Its complete usage syntax is as follows, there are three types:
git merge [-n] [--stat] [--no-commit] [--squash] [--[no-]edit]
[-s <strategy>] [-X <strategy-option>] [-S[<keyid>]]
[--[no-]allow-unrelated-histories]
[--[no-]rerere-autoupdate] [-m <msg>] [<commit>...]
git merge --abort
git merge --continue
Of course, we don't need to remember exactly how to use it. The following are the most commonly used
git merge
By default, merge is fast-forward mode to merge, and only a single branch record is retained. The main branch will directly point the latest commit to the top of the merged branch, so the commit is recorded as a straight line, and it cannot be seen that other branches were merged in.
The merge operation in this mode has a disadvantage. When we merge, it will delete the useless branch, for example, we delete the test/conflict1 branch. In this case, when the branch is deleted, all information about the branch is lost.
git merge --no-ff
--no-ff refers to forcibly closing the fast-forward mode. If you want to force disable Fast Forward mode, Git will generate a new commit on merge. It can save previous branch history. Can better view merge history and branch status.
git merge --squash
git merge --squash is used to compress some unnecessary commits. When merging, we don't want to bring some historical commits, such as temporary price increases, some useless commits, etc. These commits do not need to be in the main branch. embodied in the middle. --squash also requires an additional commit to aggregate information and then complete the final merge.