Learn Git Branching records

Learning Git Branching can be said to be the best tutorial so far, address

insert image description here
Click the question mark in the lower right corner to display commonly used commands

1. Submit

insert image description here

git commit

Submit the content and save these changes as a submission record C3, the parent node of C3 is C2

Modify commit information

insert image description here

git commit --amend

A submission record will be generated after each git commit. Using git commit --amend will append the current modification to the latest submission without generating a new submission record. For example,
C2 is submitted here, and the modification is added to C2. C2' is formed, but no new submission record is generated. The submission comments of C2 and C2' are the same, but the hash values ​​are different

2. Create and switch branches

insert image description here

git branch newImage

The newly created branch newImage points to the commit record C1

insert image description here

git checkout newImage
git commit

Switch to the newImage branch, commit C2, * indicates the current branch
Note: In version 2.23 of Git, a new command called git switch was introduced, which will eventually replace git checkout, because checkout is a bit overloaded as a single command (it carries many independent function)

git checkout -b bugFix 

Create a new branch bugFix and switch to this branch at the same time, which can be achieved by git checkout -b your-branch-name

3. merge merge

insert image description here

git merge bugFix

Merging the bugFix branch into the current main branch
Merging two branches in Git produces a special commit record, which has two parents. Translated into natural language is equivalent to: "I want to include these two parent nodes themselves and all their ancestors.", main now points to a commit record C4 with two parent nodes

insert image description here

git checkout bugFix
git merge main

Then merge the main branch into bugFix, because main inherits from bugFix, Git doesn't have to do anything, just simply move bugFix to the commit record pointed to by main

4. Merge rebase

The second way to merge branches is git rebase. Rebase is actually taking a series of commit records, "copying" them, and putting them one by one in another place
insert image description here

git rebase main
// 等价于 git rebase main bugFix

C3' is a copy of C3, and the two branches are developed in parallel after copying

insert image description here

git rebase bugFix

Switched to main. Rebase it to the bugFix branch. Since bugFix inherits from main, Git simply moves the reference of the main branch forward.

In the development community, there are many discussions about merge and rebase. Here are the advantages and disadvantages of rebase:
Advantages:
rebase makes your commit tree very clean, all commits are on one line
Disadvantages:
rebase modifies the history of the commit tree
For example, commit C1 can be rebased after C3. It looks like the work in C1 was done after C3, but it was actually done before C3.
Some developers like to preserve the commit history and thus prefer merge. While others may prefer a clean commit tree, prefer rebase

5. Separate HEAD

HEAD is a symbolic reference to the current branch. The separated HEAD is to point to a specific commit record instead of the branch name
insert image description here

git checkout C1 //这里的C1表示提交记录的哈希值

State before command execution: HEAD -> main -> C1
HEAD points to main, main points to C1
after execution becomes: HEAD -> C1

6. Relative references

It is inconvenient to specify the commit record by hash value, so Git introduces relative references
Use ^ to move up 1 commit record
Use ~num to move up multiple commit records, such as ~3

insert image description here

git checkout main^

insert image description here

git checkout HEAD~4

Forcibly modify the branch location, you can directly use the -f option to make the branch point to another commit
insert image description here

git branch -f main HEAD~3

The above command will force the main branch to point to HEAD's level 3 parent commit

A more complex example
insert image description here

git branch -f main C6
git checkout HEAD^
git branch -f bugFix HEAD^

7. Undo changes

Undoing changes consists of a bottom-level part (individual files or fragments in the staging area) and an upper-level part (how the change was undone). The main focus here is on the latter
insert image description here

git reset HEAD~1

git reset undoes changes by rolling back several commit records of branch records. After reset, the changes made by C2 are still there, but they are not added to the temporary storage area. Reset is mainly used for branches managed by itself

While it's convenient to use git reset on a local branch, this method of "rewriting history" doesn't work on the remote branch everyone uses together!
In order to undo the changes and share them with others, we need to use git revert
insert image description here

git revert HEAD

The new commit record C2' introduces changes -- changes that happen to undo the commit C2. That is to say, the state of C2' is the same as that of C1

8. Copy the commit record to the current branch (selection)

insert image description here

git cherry-pick C2 C4

Copy C2 and C4 and commit to the current main branch

9. Interactive rebase

If you want to find the desired record from a series of commit records, you can use interactive rebase, which refers to the rebase command with the parameter --interactive, abbreviated as -i if you add this option after the
command , Git will open a UI interface and list the alternative submission records that will be copied to the target branch. It will also display the hash value and submission description of each submission record. The so-called UI window is generally in a text editor (such as Vim) to open a file. A dialog box is used in the course to simulate these operations

When the rebase UI interface is open, you can do 3 things:
adjust the order of the commit records (drag and drop with the mouse)
delete the commits you don't want (done by switching the pick state, close means you don't want this Commit record)
merge commit, which allows you to merge multiple commit records into one

insert image description here
insert image description here

git rebase -i HEAD~4

Open the UI interface here to modify the 4 submissions above HEAD, delete the submission C3, and modify the order of C4 and C5

10. Label

Branches are easy to change, and most branches are temporary and changing all the time. tag can (in a way - because a tag can be deleted and recreated in another location with the same name) permanently name a particular commit as a milestone, which can then be referenced like a branch
insert image description here

git tag V1 C1

Create a label V1 pointing to the commit record C1. If you don't specify a commit record, Git will use the location pointed to by HEAD

recent tags

Since tags play the role of "anchor" in the code base, Git also specially designed a command to describe the anchor point (that is, the tag) closest to you, which is git describe The syntax of git describe
is :

git describe <ref>

ref can be any reference that Git recognizes as a commit record. If you don't specify it, Git will use your current location (HEAD).
It outputs something like this:

<tag>_<numCommits>_g<hash>

tag indicates the tag closest to the ref, numCommits indicates how many commit records the ref differs from the tag, and hash indicates the first few digits of the hash value of the commit record represented by the ref you give as the ref commit
record When there is a label, only the label name is output

insert image description here

git describe main
v1_2_gC2 //输出
git describe side
v2_1_gC4 //输出

11. Select the parent commit record

The operator ^ is the same as the ~ operator, and can also be followed by a number num
A merge submission has two parent submissions, num refers to a parent submission, and the "first" parent submission of the merge submission is selected by default
insert image description here

git checkout main^

By default, it will return to the first parent submission record. In the example diagram, the first parent submission record refers to the submission record directly above the merge submission record

insert image description here

git checkout main^2

Back on another parent commit

These operators also support chaining operations
insert image description here

git checkout HEAD~^2~2

12. Remote warehouse

git clone 地址

Create a local copy of the remote repository

insert image description here
o/main means the remote branch, where o means origin, and the remote branch has a special attribute. When you switch to the remote branch, it will automatically enter the detached HEAD state. Git does this for the reason that you cannot directly operate on these branches, you have to complete your work elsewhere, (after updating the remote branch) and then use the remote to share your work. When we get data from the remote
warehouse When the remote branch is also updated to reflect the latest remote repository

fetch

insert image description here

git fetch

C2 and C3 are downloaded to the local warehouse, and git fetch completes the only but very important two steps:

  1. Download missing commit records from the local repository from the remote repository
  2. Update the remote branch pointer (such as o/main)

git fetch does not change the state of your local repository. It will not update your main branch, nor will it modify the files on your disk. You can understand git fetch as a simple download operation. If the remote warehouse has multiple branches, it will download all the commit records to each remote branch

pull

When there are new commits in the remote branch, you can merge the remote branch just like merging the local branch. That is, you can execute the following commands:

git cherry-pick o/main
git rebase o/main
git merge o/main

Since the process of first grabbing updates and then merging them into local branches is very common, Git provides a special command to complete these two operations

git pull

insert image description here

git fetch
git merge o/merge

Downloaded C3 with fetch, then merged C2 and C3 into C4, now our main branch contains updates in the remote warehouse
and git pull is shorthand for git fetch and git merge, using git pull can replace the above two commands, similar git pull --rebase is the abbreviation of fetch and rebase
pull operation, the commit record will be downloaded to o/main first, and then merged into the local main branch

push

insert image description here

git push

git push uploads your changes to the remote warehouse, the remote warehouse receives C2, the main branch in the remote warehouse is also updated to point to C2, our remote branch (o/main) is also updated, and all branches are Synced
NOTE - The behavior of git push with no arguments is related to a Git configuration called push.default. Its default value depends on the version of Git you are using

insert image description here
In this case, git push will fail, because your latest commit C3 is based on C1 in the remote branch. And the branch in the remote warehouse has been updated to C2, so Git rejected your push request, so in actual development, you must first git pull to update to the latest before submitting

insert image description here

git fetch
git rebase o/main
git push

Use git fetch to update the remote branch in the local warehouse, then use rebase to move our work to the latest submission record, and finally push it to the remote warehouse with git push

git pull --rebase
git push

You can also use git pull --rebase to simplify the command
insert image description here

git fetch
git merge o/main
git push

Using git fetch to update the remote branch in the local warehouse, then merging the new changes into our local branch (in order to include the changes in the remote warehouse), and finally we use git push to push the work to the remote warehouse

git pull
git push

Simplify commands with git pull

13. The remote server rejects! (Remote Rejected)

If you are working in a large cooperative team, it is likely that main is locked and cannot be submitted directly to main, requiring some Pull Request process to merge changes. If you directly commit (commit) to the local main, and then try to push (push) changes, you will receive a message similar to this: !
[remote server rejected] main -> main (TF402455: Not allowed to push (push) this branch ; You must use a pull request to update this branch.)

The remote server refuses to directly push (push) to main, because the policy configuration requires pull requests to submit updates.
You should follow the process to create a new branch, push (push) this branch and apply for a pull request

insert image description here

git reset --hard o/main
git checkout -b feature C2
git push origin feature

Reset first to ensure that the main branch is consistent with the remote server, here use --hard hard reset, you can omit that option to avoid trouble! But to record the default in Git is --mixed

14. Remote Tracking

When you clone, Git creates a remote branch (such as o/main ) in the local repository for each branch in the remote repository. Then create a local branch that tracks the active branch in the remote repository. By default, this local branch will be named main, and main is set to track o/main - which means specifying the push destination for the main branch and The target to merge after pulling.
This also explains why you see the following output when cloning:
local branch “main” set to track remote branch “o/main”

There are two ways to set this tracking property, the first is to switch to a new branch through the remote branch, execute:

git checkout -b totallyNotMain o/main

would create a branch called totallyNotMain that tracks the remote branch o/main

insert image description here

git checkout -b foo o/main
git pull

Switch to a new branch named foo, let it track main in the remote warehouse, use the implicit target o/main to update the foo branch, note that main has not been updated

The second method is to use: git branch -u command, execute:

git branch -u o/main foo

This way foo will track o/main. If you are currently on the foo branch, you can also omit foo:

git branch -u o/main

15. Parameters of Git Push

Parameters can be specified for push, the syntax is:

git push <remote> <place>
git push origin main

The command is: cut to the "main" branch in the local warehouse, get all the submissions, and then find the "main" branch in the remote warehouse "origin", and add all the submission records that are not in the remote warehouse. In fact, it is to The location of the two repositories that are synchronized

insert image description here

git checkout C0
git push origin main

By specifying parameters, the main branch in the remote warehouse is updated
If the above git push does not specify parameters, the command will fail because the HEAD we switched to does not track any branches

When specifying the place parameter as main, we also specify the source and destination of the commit record. If the names of the source and destination branches are different, use the following command

git push origin <source>:<destination>

insert image description here

git push origin foo^:main

source can be any location that Git can recognize, foo^ resolves to a location, and uploads all commit records that are not included in the main branch of the remote warehouse

insert image description here

git push origin main:newBranch

If the target branch you want to push to does not exist, Git will help you create this branch in the remote warehouse based on the name you provided

insert image description here

git push origin :foo

You can also not specify the source, by passing a null value source to push, the branch in the remote warehouse will be deleted

16. Parameters of Git fetch

The place parameter of git push, and the source:destination separated by colons, these parameters can also be used for git fetch, but in the opposite direction (because it is downloading instead of uploading)

insert image description here

git fetch origin foo

Only the latest commit record in the foo branch in the remote warehouse is downloaded, and o/foo is updated.
Why does Git put the new commit in o/foo instead of my local foo branch? Because you probably have unfinished work on the foo branch and you don't want to mess it up

You can also specify source:destination, note: source refers to the location in the remote warehouse, and destination is the location where the submitted local warehouse is to be placed. It is just the opposite of git push, and developers rarely do it, so I won’t demonstrate it here

insert image description here

git fetch origin :bar

If the fetch is empty to the local, a new branch will be created locally

17. Git pull parameters

The following commands are equivalent in Git:

git pull origin foo 相当于:
git fetch origin foo
git merge o/foo

besides…

git pull origin bar~1:bugFix 相当于:
git fetch origin bar~1:bugFix
git merge bugFix

pull can also use source:destination
insert image description here

git pull origin main:foo

First create a branch called foo locally, download the commit record from the main branch in the remote warehouse, merge it into foo, and then merge it into our current branch bar

reference

The most complete Git advanced course at station B

Guess you like

Origin blog.csdn.net/sinat_34014668/article/details/130662984