Git learning seven: Branch other knowledge

Hello everyone, let's continue to learn Git. Your legendary house building story is really back!

Remember who you are? You are the backbone of the country! And don't forget the old Wang next door you just hired.

1. Merger conflict

  • According to my train of thought, there will be any conflict between you and Lao Wang next door, but who are you? You are... Forget it. I can't boast any more. Wait a minute, I'll read the script. Ah, my sixth sense is true. You and Lao Wang really had a conflict when building a house: you wanted to lower the height of the roof by 0.01 cm, and Lao Wang raised the height of the load-bearing wall by 0.01 cm. Imagine that if you can't, you think you have a conflict with Lao Wang next door!

The examples used in this section are

>A new warehouse with branch master, t1, t2; There is an index.txt file under the branch, as follows

Branch diagram:

1.merge conflict

The following is about the conflict when using the git merge command.

>Branches t1 and t2 respectively modify the contents in index.txt (all changes are in the first sentence) as follows and commit respectively

  • t1>index.txt
Baby shark 
Mommy shark doo doo doo doo doo doo
Daddy shark doo doo doo doo doo doo
Grandma shark doo doo doo doo doo doo
Sunny day doo doo doo doo doo doo
Go and spend it doo doo doo doo doo doo
Tight away doo doo doo doo doo doo
Shark attack doo doo doo doo doo doo
What the fact doo doo doo doo doo doo
We safe at last doo doo doo doo doo doo
  • t2>index.txt
Baby shark doo doo doo doo doo doo doo doo doo doo doo
Mommy shark doo doo doo doo doo doo
Daddy shark doo doo doo doo doo doo
Grandma shark doo doo doo doo doo doo
Sunny day doo doo doo doo doo doo
Go and spend it doo doo doo doo doo doo
Tight away doo doo doo doo doo doo
Shark attack doo doo doo doo doo doo
What the fact doo doo doo doo doo doo
We safe at last doo doo doo doo doo doo

Branch diagram:

>We use the git merge command to merge under branch t2, and the normal mode will be used at this time

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo5 (t2)
$ git merge t1
Auto-merging index.txt
CONFLICT (content): Merge conflict in index.txt
Automatic merge failed; fix conflicts and then commit the result.

It can be found that the two branches conflict at index.txt. Call git status to check the status

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo5 (t2|MERGING)
$ git status
On branch t2
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:   index.txt

no changes added to commit (use "git add" and/or "git commit -a")

From the above, we can see that branch t2 has been modified. What has been modified? Let's open the file to see:

<<<<<<< HEAD
Baby shark doo doo doo doo doo doo doo doo doo doo doo
=======
Baby shark
>>>>>>> t1
Mommy shark doo doo doo doo doo doo
Daddy shark doo doo doo doo doo doo
Grandma shark doo doo doo doo doo doo
Sunny day doo doo doo doo doo doo
Go and spend it doo doo doo doo doo doo
Tight away doo doo doo doo doo doo
Shark attack doo doo doo doo doo doo
What the fact doo doo doo doo doo doo
We safe at last doo doo doo doo doo doo

From the previous modification, we can see that the content modified by branch t2 is above the equal sign and the content modified by branch t1 is below the equal sign. The two conflict in this line.

In case of conflict, we will decide according to the actual situation. After combining the two, we will modify the document (the change is only in the first sentence) as

Baby shark doo doo doo
Mommy shark doo doo doo doo doo doo
Daddy shark doo doo doo doo doo doo
Grandma shark doo doo doo doo doo doo
Sunny day doo doo doo doo doo doo
Go and spend it doo doo doo doo doo doo
Tight away doo doo doo doo doo doo
Shark attack doo doo doo doo doo doo
What the fact doo doo doo doo doo doo
We safe at last doo doo doo doo doo doo

Then use the add and commit methods to resubmit. Here you can also use the git commit -a command to submit file modifications. Note that this command is only applicable to the file already in the latest commit version. If it does not exist, you'd better use the two-line statement.

#t2
git commit -a -m "t2 merge with t1"

After that, the merge conflict is resolved. Take a look at the branch diagram:

It should be noted that merging two branches to the same file does not necessarily lead to merge conflicts, but changing to the same line in the same file will certainly lead to merge conflicts

2. Cherry pick / rebase conflict

Roll back the branch t2 above. This time, we use the GIT cherry pick command to merge

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo5 (t2)
$ git cherry-pick t1
Auto-merging index.txt
CONFLICT (content): Merge conflict in index.txt
error: could not apply 8453c28... t1 modify index.txt
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

Similarly, let's use the git status command to check

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo5 (t2|CHERRY-PICKING)
$ git status
On branch t2
You are currently cherry-picking commit 8453c28.
  (fix conflicts and run "git cherry-pick --continue")
  (use "git cherry-pick --skip" to skip this patch)
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   index.txt

no changes added to commit (use "git add" and/or "git commit -a")

You can find that index.txt has also been modified,

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo5 (t2|CHERRY-PICKING)
$ cat index.txt
<<<<<<< HEAD
Baby shark doo doo doo doo doo doo doo doo doo doo doo
=======
Baby shark
>>>>>>> 8453c28 (t1 modify index.txt)
Mommy shark doo doo doo doo doo doo
Daddy shark doo doo doo doo doo doo
Grandma shark doo doo doo doo doo doo
Sunny day doo doo doo doo doo doo
Go and spend it doo doo doo doo doo doo
Tight away doo doo doo doo doo doo
Shark attack doo doo doo doo doo doo
What the fact doo doo doo doo doo doo
We safe at last doo doo doo doo doo doo

So let's modify the file, and then add it to the Index using git add command instead of commit; because the cherry pick command will not generate a new commit, it only copies the commit implementation internally.

Finally, restore git cherry pick and use the following command

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo5 (t2|CHERRY-PICKING)
$ git cherry-pick --continue
[t2 73e312a] t1 modify index.txt
 Date: Sun Oct 10 16:43:11 2021 +0800
 1 file changed, 1 insertion(+), 1 deletion(-)

Because the contents of the copied commit may be changed due to modification, the original commit information can not describe the merged commit well. Therefore, Git will automatically call the vim editor to let you modify the commit information

In this way, cherry pick is completed. Let's look at the branch diagram (I didn't modify the commit information here):

Because as like as two peas, the rebase command is implemented through cherry-pick, the merge conflict resolution methods are almost the same, except for the last recovery rebase command.

git rebase --continue

3. Binary file conflict

Fallback branches T1 and T2 to the original master branch derivative version

Now, an animal.jpg image file (binary file) is added to branches T1 and T2, but the contents are different:

  • t1>animal.jpg

  • t2>animal.jpg

At this time, we use the git merge command to merge (and so on for other merges). There is no doubt that there will be merge conflicts

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo5 (t2)
$ git merge t1
warning: Cannot merge binary files: animal.jpg (HEAD vs. t1)
CONFLICT (add/add): Merge conflict in animal.jpg
Auto-merging animal.jpg
Automatic merge failed; fix conflicts and then commit the result.

For binary files (image files here), we can't have both. We can only abandon one and choose the other, so we should choose carefully!

Select the file for this branch:

git checkout --ours [file name]

OR select a file from another branch

git checkout --theirs [file name]

Here I choose the cat that is obviously more lovely (if you want to think dog is more lovely, choose dog). The file is in this branch (t2)

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo5 (t2|MERGING)
$ git checkout --ours animal.jpg
Updated 1 path from the index

After that, the merge command is used to resolve the merge conflict, and then submit the commit again

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo5 (t2|MERGING)
$ git commit -a -m "choose cat as animal.jpg"
[t2 18f5ab1] choose cat as animal.jpg

Take a look at the branch diagram:

In case of binary file conflict in cherry pick and rebase merging, it is similar to merge merging, which will not be repeated here.

2. Go back and start over

"If I had made another choice, I would not have lived like this."

Git gives you a chance to reform, so that you can open branches in any commit version of the history, on the premise that you need to know the corresponding commit ID

It can be found that any of the above branches cannot reach 5ab1 and other commit through HEAD ^

Now we want to 5ab1 open up a branch

  1. Two sentence code implementation
git checkout 5ab1  #Switch to the corresponding commit
git checkout -b t3   # Open branch
  1. One sentence of code
git branch t3 5ab1  #Branch at a commit
  1. One sentence code implementation two
#Choose one of the following sentences to open a branch at a commit and switch to it
git switch -c t3 5ab1
git checkout -b t3 5ab1

3. Modify history

1. Modify the last commit record

  • After the conflict, you feel very dissatisfied, and the people you hire don't listen to your suggestions. So one day, you secretly ran to his house and drew a little pig's head on the door 🐷, When you came back, you found that Lao Wang was still concentrating on testing the sound insulation effect of the load-bearing wall in your bedroom. You felt very ashamed and regretted what you had done. So you hurried to his door and wiped off the pig head pattern.

>After you create a new warehouse, you can do the following

touch YouArePig.html
git add .
git commit -m "add YouArePig.html"

Then we output the commit log

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo6 (master)
$ git log --oneline
6cbe2df (HEAD -> master) add YouArePig.html

It can be found that any of our original operations will not affect the 6cbe2df corresponding record in the log. If others see this commit ment record in the actual development of the team, you will not suffer! So we must modify this record.

Let's change the name of the file first

git mv YouArePig.html welcome.html

Then we need to submit to the last commit record, using the parameter -- amend

git commit --amend -m "add welcome.html"

Finally, let's take a look at the commit log

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo6 (master)
$ git dog
* 52bc8a9 (HEAD -> master) add welcome.html

The git dog command here is an abbreviated command described in the previous article

The last commit record of this modification also applies to other branches.

2. Modify history

Obviously, you in front of the screen are not satisfied that you can only modify the last record, so now let's introduce the command to modify any record

The git rebase command described earlier has a powerful interactive mode that can be used to change past history

git rebase -i [commit Identification code]

The commit ID refers to the modification range from the current commit to the specified commit

>Here is an example, as shown in the figure

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo1 (cat)
$ git dog
* 0d9f7bf (dog) add food1.html
* d4f371a (HEAD -> cat, temp, master) add demo.html
* 782fb0e modify newFirst.html
* 7b2a50e add .gitignore and dreams
* fad681e rename newSecond to newFirst
* 1e220a4 create a roof
* c433657 no door and window
* 94ddea2 create a window
* 0241363 create a door

If you want to modify the scope of all, you can select the lowest commit ID. note that all here refers to all commit of cat branch

git rebase -i 0241363

After that, Git will enter the interactive mode and call the vim editor, as shown in the figure below

You can see that there are commit log records above. However, it should be noted that the records are in reverse order to the git log output. The above is the earliest commit

You can see that each commit record is preceded by a word pick, which is an instruction

instructionsabbreviationmeaning
pickpKeep the commit without making any changes
rewordrOnly change the commit information
squashsMerge previous commit
editeModify a commit
dropdDelete a commit

1. Modify the commit information

As shown in the figure, after modification, the vim editor will pop up after the archive leaves to edit the corresponding commit information.

However, the output log will find

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo1 (cat)
$ git dog
* 8c2a89e (HEAD -> cat) add food1.html
* 578aa1c add demo.html
* 29b8020 modify newFirst.html
* 32548b7 add .gitignore and dreams
* 89f84a5 rename newSecond to newFirst
* af5f408 create a roof
* 285633b no door and window
* 5c79baa create a window for me
| * 0d9f7bf (dog) add food1.html
| * d4f371a (temp, master) add demo.html
| * 782fb0e modify newFirst.html
| * 7b2a50e add .gitignore and dreams
| * fad681e rename newSecond to newFirst
| * 1e220a4 create a roof
| * c433657 no door and window
| * 94ddea2 create a window
|/
* 0241363 create a door

In fact, the so-called modification is to copy the commit record in that range, generate a parallel space-time (new branch), and then modify it. The original commit record cannot be modified. However, we can use the forced pointer to complete the branch. It seems that it has been modified.

The latter instructions are the same. In fact, they are replication branch merging in essence

2. Merge the previous record

There are warehouses as follows

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo7 (master)
$ git dog
* 776a58b (HEAD -> master) add b.txt
* 3c9437d add a.txt
* e6ef683 add index.html

Continue to use interactive mode and we will merge

Similarly, when the archive exits, the vim editor will be called to edit the commit information. Then we check the log and find that the two commit records have been merged

3. Modify the specified commit record

Let's use the example just merged above and modify it now

Then there will be

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo7 (master)
$ git rebase -i e6ef
Stopped at 9fd72b8...  add a & b .txt
You can amend the commit now, with

  git commit --amend

Once you are satisfied with your changes, run

  git rebase --continue

Now we can modify the commit record. The modification here can be regarded as any operation, or we can continue to add the commit or rollback the version

Here we do two operations: reset first and then commit

#reset
git reset HEAD^ --hard
#commit
touch c.txt
git add .
git commit -m "add c.txt"

In fact, this will separate the HEAD pointer and point to a parallel space (new branch). Any operation now takes place in the parallel space

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo7 (master|REBASE 1/1)
$ git dog
* e8b6434 (HEAD) add c.txt
| * 9fd72b8 (master) add a & b .txt
|/
* e6ef683 add index.html

Now let's exit parallel space with the following command

git rebase --continue

Are you familiar with it? This is also the command used by rebase to recover merge conflicts

Now check the log

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo7 (master)
$ git dog
* e8b6434 (HEAD -> master) add c.txt
* e6ef683 add index.html

If you know the rebase command, it's easy to know what happened above.

You remember that the last step of the rebase command to merge branches is to change the branch pointer, which will point to the position of the HEAD pointer; Therefore, the original commit cannot be traversed and output displayed

4. Others

In interactive mode:

  1. To delete a commit record, you can change the previous instruction to drop, or directly delete that record
  2. Change the order of commit records and change places directly.

In fact, the interaction mode here is not very different from the principle of merging branches. If you don't understand, please master the principle of git rebase merging branches first

4. Fallback version

1.ORIG_HEAD

When performing some dangerous operations (merging, etc.), Git will use ORIG_HEAD to save the commit originally pointed to by the HEAD pointer

If a branch passes through the git rebase command, the following two commands are different

# 1
git reset HEAD^
# 2
git reset ORIG_HEAD

The first command stands for backing out the previous commit of this branch, and the second command stands for the latest commit of the branch before backing out to rebase

Therefore, ORIG_HEAD is often used to undo the git rebase command operation

2.revert command

In fact, we can handle the fallback version through the reset or rebase commands just introduced. Why do we talk about the fallback version? Because in team cooperation, we are limited to the principle of team development, we may not have the opportunity to use these commands, because these commands will change the history, which is a major task in the team project and cannot be easily executed!

>Here's an example. Use the reset command to rollback the version

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo7 (master)
$ git dog
* e8b6434 (HEAD -> master) add c.txt
* e6ef683 add index.html

>After fallback, as follows

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo7 (master)
$ git dog
* e6ef683 (HEAD -> master) add index.html

It can be found that the history has been modified, which is not a good thing in team cooperation. Here we do a time machine to start again

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo7 (master)
$ git dog
* e8b6434 (HEAD -> master) add c.txt
* e6ef683 add index.html

Now let's roll back the version with the git revert command

git revert HEAD --no-edit

Here, HEAD means to roll back the current commit to the previous commit, while the following – no edit parameter means to use the default information instead of editing the commit information

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo7 (master)
$ git dog
* 3b9cd82 (HEAD -> master) Revert "add c.txt"
* e8b6434 add c.txt
* e6ef683 add index.html

Seeing the above commit records, you may be surprised at the beginning why the records are not reduced but increased by one? Maybe you can immediately understand that the revert instruction is "make a new commit to cancel the commit you don't want", so the number of commits is added

By looking at the file, we also verified this: c.txt is missing

littledot@DESKTOP-DUT0I3O MINGW64 /e/Git_repo/Repo7 (master)
$ ls
index.html

You can find that the above commit log is very "polite", and you can tell us about the fallback version. Therefore, it is recommended to use the revert command in the team (sometimes it is mandatory), but it is a little "too polite" in personal projects. You can directly use the reset command

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-zcpyc38o-163419782047)( https://gitee.com/littledot123/picgo/raw/master/picture/202110132032960.png )]

5. Nonsense time

Less nonsense, you can move on to my next article.

Keywords: git

Added by jaronblake on Wed, 13 Oct 2021 15:58:34 +0300