sequence
The first half belongs to the foundation, and the second half belongs to the advanced. From elementary to intermediate to advanced that I can’t handle. The full text is more than 12000 words, super dry super dry kind. Halfway through, however, MY body suddenly shook. Was I building a wheel? Then I quietly searched Git. Huh? So many git articles, oh my God, I lost myself in thought, I frowned on a few articles, from the so-called close-up work of 20 thousand words truth, to the complete detailed Git series of tutorials. It’s a little bit of a wheel, but as I continued to read their content, IT was a bit of an Epiphany, because I realized that my article was quite unique. Finally, I came to the conclusion that I did not build wheels. This is a highly available, highly extensible and high-performance Git and Gerrit article. Use actual combat to promote thinking, kill popular Git knowledge, from a common perspective to expand the deep knowledge, and then abstract out the mystery of Git we can understand. Don’t stick to API, don’t be afraid of other wheels, don’t be timid, just do it.
This paper is based on my unique understanding of merge and patch on other people’s commit, so as to generate a better commit, and then leave better merge and patch for everyone in the future. The technology keeps improving in patch after patch.
Cut to the chase
In actual project development, flexible use of Git and Gerrit is a very important thing, on the one hand, can improve the team development efficiency, on the other hand, can control the quality of the project code. However, for Gerrit, some students may not have used, and there are some skills of Git that you may not have mastered, today I will share with you, while sharing, you also have a lot of immediate harvest.
PS: Why do I say I have a lot to gain myself? It goes like this: When I choose to write a blog, I will go to the thorough understanding of my writing this blog related knowledge, the deep understanding of the process, I’m going to read all kinds of information, and then to analyze, finally summarizes my own characteristics of the learning, for me, is a kind of harvest and senior advanced instant.
Why git
Here we use git, we should go to understand the background of the emergence of Git, the specific story does not say, their wiki. Here I will briefly talk about the emergence of Git, in the technical background.
Git is an open source distributed version control system. The source code is also open source on Github and can be searched by yourself. When it comes to distributed version control systems, it should be associated with centralized version control systems, such as SVN, whose full name is Subversion.
So what’s the difference? Here are two pictures to compare:
SVN:
GIT:
The main differences between the two can be basically analyzed from the picture. Such as:
git
It can be developed offline,svn
Can’t offlinegit
To deal withmerge
The advantages of rollingsvn
Git’s content is more complete, the SHA-1 algorithm is used, and Git can operate branch more flexibly. Wait, no wheels here, see this blog post:
Advantages and disadvantages of SVN compared with Git
SVN is not as good as Git, but these are two different version control systems. You can’t just say who is better than who is worse. Here is an interesting blog about SVN whitewashing.
What 90% of people don’t know: some misconceptions and truths about SVN and Git
To summarize, SVN is better for project management and Git is better for code management.
Why gerrit
Let’s look at the wiki introduction:
Gerrit is an open source code review software designed specifically for CR.
Version control system
Version control system of the three axe
Here are the three axes of version control:
The first board axe: store content
Second plate axe: tracking content changes
Hammer # 3: Distribute content and history with collaborators
By understanding the three axes above, you understand the essence of a version control system, so read on without explaining it here and try it out for yourself.
History of version control systems
Git is one of the most popular front-end systems in the world, and it will be one of the most popular front-end systems in the world. In order to expand the knowledge of version control, it is necessary to understand the development history of version control systems.
From manual copy diff to patch, to RCS that introduced mutex, to CVS that introduced branch for the first time, to SVN that implemented atomic level merging, and now to the new king Git. Every age has its own pride. Here I recommend a very good blog:
Blogger: Vamei
Blog post: Version Management three Kingdoms (CVS, Subversion, Git)
This article explains the whole history of version control system perfectly, from the personal manual copy and compression package at the beginning, to the later patch by diff (commonly referred to as patch), and then the patch was communicated by email. RCS CVS SVN Git git git git git git
Here I modify the last paragraph of the article:
Unlike The Three Kingdoms,VCS
The three countries have not yet decided the final outcome, perhapsSVN
Will continue to play a role in important projects, butgit
Eventually it will dominate, or at least the front end.
Git and Gerrit
Sometimes we don’t really care why we call git or gerrit. But many names have their own stories, such as vue and React. You can look it up, it helps us understand them more visually.
The naming of the git
For example, the origin of the word git can be found in a passage on Wikipedia:
Quoting Linus: “I’m an egotistical bastard, and I name all my projects after myself. First ‘Linux’, now ‘Git'”.(‘git’ is British slang for “pig headed, think they are always correct, argumentative”).
Translation: I am an arrogant jerk who names all my projects after myself. First “Linux”, now “Git”. Git is British slang for pig heads and thinks they are always right and controversial.
Is not found that in fact naming also has its own story.
For another example, My in MySQL is not My consciousness. MySQL is named after the MySQL database as follows:
Its name is a combination of “My”, the name of co-founder Michael Widenius’s daughter,[7] and “SQL”, the abbreviation for Structured Query Language.
The naming of gerrit
Now that I’ve said how Git got its name, I’ll be brief. Gerrit is named after the first word of Dutch designer Gerrit Rietveld.
Why use Git
It’s also worth asking why we use Git.
Intuitively, we use it naturally and find it works. Then we can ask ourselves why Git works so well. If we read the blogs mentioned above, we may already have the answer. In fact, many great things are born in the context of a certain dimension of birth, which solves the pain points that most of its peers have not solved.
So now we use Git, we think it is very good, but in fact we don’t seem to know what kind of pain point git has solved, we just know it is good. When I say this, I want to illustrate that to understand something, it is best to understand the historical background or technological background in which it was born. Why use Git? Don’t panic, the question is not big, in fact, the answer has been mentioned in the front.
Talk about git-flow
There are many blogs on the web about the Git-flow development process that I won’t cover here, but WHAT I want to cover is this:
It is git-flow in the real sense to sum up a Git development mode suitable for this project.
How to make a good Git-flow
Currently, the main code hosting platforms are github, GitLab, Coding and code Cloud. This is the mainstream code hosting platform I know of (excluding Bitbucket, because there are not many in China). Github’s recent move to allow private repositories as well as personal development means that all four code hosting platforms can now build private repositories for free, which is a big moment.
After working on several projects, I was thinking about what a good development model (development-only) would look like, and finally I came to a key factor:
A good development mode can improve the team’s development efficiency and improve the quality of the team’s code. (This is not nonsense, manual funny)
Everything we’ve mentioned above, both SVN and Git, is about optimizing existing development patterns. Then, how to develop git-flow of this project style according to the characteristics of this project? I’ll share some of my own thoughts below.
Project background
Currently involved in a large project with dozens of front-end developers using Git version control. I am responsible for adding Gerrit to the project and helping other developers make a smooth transition to the Gerrit development model, which is generally referred to as:
I am responsible for solving any problems with Git and Gerrit operation.
You cannot have your cake and eat it
In my experience, improving the quality of the team’s code is a sure way to reduce the team’s development efficiency, which means less work is produced in average time.
Why do you say that? Because it makes sense, I’ll use V8 for an example:
Take the V8 engine for example, the OPTIMIZATION of JS code by V8 is not optimized by JIT compiler, but by JIT optimization of some code and native code generation of other code.
The reason is simple:
The better optimized it is, the more time it takes to analyze and generate code. A longer wait is acceptable for compiled versions like C++, but for JavaScript, even 200ms is a test of the user experience.
I use this example to illustrate a point from the field of software programming:
That is, we should not blindly pursue quality, but combine quality and efficiency together to achieve an optimal solution.
Personally, I think the online standard Git-flow mode may be suitable for those open source projects, or important projects within the company. In fact, the background of the birth of Git is mainly to make the open source code version control become more powerful. Github has made Git very popular. Let’s take a look at the standard Git-flow pattern on the web.
Is it dazzling to see, are a little scared, I just do a version control, is it necessary to be so complicated?
First of all, there is no need to be so complicated that you should not be scared to use Git. The Git-flow pattern above is arguably the best practice for version control with Git. But I don’t think this is appropriate for most business projects.
What percentage of front-end projects are developed using the standard Git-flow pattern in large or small companies? I think it’s almost nothing, or even 10%, I think it’s a miracle. If the project is on a tight schedule and iterates fast, it’s almost impossible to follow this pattern, so how?
I think it should be: after analyzing the time of the project and the speed of iteration, make a plan that can not only control the code quality and version management, but also make the development process less tedious, so as to ensure certain development efficiency. This is a good Git-flow,
In plain English:
Do what’s comfortable. Use your imagination.
So when you want to learn git-flow development, and then go to the Internet to search the blog, git-flow is a bit abstract. Don’t be afraid at this point, I don’t think this standard abstract Git-flow is the git-flow of your current project.
You should learn the idea of the standard Git-flow pattern.
For example, several key branches are used to fine-control the lifecycle of the version, and branches are used to separate the code of each lifecycle to ensure the purity of the code of each lifecycle of the version.
What is the consciousness of purity?
For example, if you are halfway through developing the next version of code, it will not appear in the current version of online code, so purity can be understood as such.
What I’m trying to say is:
Instead of learning how to use Git-Flow, it’s important to understand the idea behind a great version control system solution. Once you understand the idea in depth, you’ll be able to do it with other version control software.
How is Git-flow implemented in large projects
Taking a large project I am currently involved in as an example, here is how to summarize the Git-flow flow of this project in practice.
Feature branch dev dev dev dev dev dev dev dev dev dev dev
The dev branch serves two purposes:
One is the feature branch and the other is the Develop branch. When it is time to release a new version, a branch of the dev-xx family is cut from dev and used to release a version. Well, it’s that simple and straightforward.
When the project started:
The project code was hosted on an internal GitLab, and there was no CR when the project started. All developers can submit code to the Dev branch.
Why is that?
The purpose is to improve the development efficiency, because the project is in the stage of rapid development, if you pay too much attention to quality assurance, it will increase the labor cost, reduce the development efficiency, and finally run counter to the rapid development, which is also in line with the saying: premature optimization is hell.
But increasing the speed of development means taking risks.
For example, a colleague does something wrong and the code is missing. Let me tell you a classic case I met (briefly about this big movie) is:
You (on behalf of a colleague) mishandled the merge and successfully lost a lot of other colleagues’ code, but without knowing it, thought you were doing the right thing and committed the code to the Dev branch. At this point, the commit timeline continues to move forward, and after a long time, you notice, and then suddenly at the whole crew, and we understand. Then when you find out, you decide to take care of the problem yourself, but you don’t think of the whole thing, just think of using SourceTree to roll back the code to the merge error index, but you accidentally click on the wrong branch and roll back the dev branch code to the previous version. Therefore, the remote dev branch, from the last version to the current version of the code is gone, records are gone…
The above example is basically the biggest problem in the process of git operation besides deleting libraries. The reasons for this can be summarized as follows:
- Take a branch
merge
When it gets to another branch, it mishandles it. - As a result, the development of each product line lasted for half a day on the wrong code. Due to the excessive personnel involved in the project, there were many times within half a day
commit
“And you know. - Use it without thinking it through
reset
This horrible command to operate on otherscoder
的commit
. reset
The wrong branch caused a large version of the code to get killed and the remote records to disappear.
Is the reason I gave quite sufficient? Then how did this matter be solved? After discussion, there are two options:
First: by rolling back the branch to commit before the merge error. The commits that continue after the error are then added one by one. The problem with this approach is that because the remote records are gone, you have to rely on some development that has a relatively complete record to do this, but there is no guarantee that the record is complete.
The second one: leave it to each product line to claim by themselves, solve their own code loss, where lost, where to replace, adopt the responsibility system.
Which solution was adopted?
After discussion, the second scheme was adopted.
One might ask, why not use the first option? The reasons are as follows:
One: The remote records are gone, which hurts.
Second: trust the local record of a particular development to be unreliable, and finally have each product line CR their own code to see if it is fully fixed.
After comprehensive consideration, we finally adopted the second plan, which directly let each product line claim. Although it is troublesome for everyone, we can let each product line CR their own code, which is more secure and reliable.
This incident also proves that if you don’t limit permissions properly while improving development efficiency, you can have accidents you don’t want to see in the future.
One might also ask why there is no CR mechanism, such as why gerrit was not played in the first place.
My personal view on this is as follows:
Gerrit means increased operational complexity and increased labor costs, such as freeing up more people for CR for an App-level project. And the general project at the beginning, manpower is tight, so this will undoubtedly increase the cost of the project. If you can guarantee that there will be no code problems through personal technical literacy, then you can skip CR. Without the application, the project iterated many versions without any problems in version control, which also shows that some optimization does not have to be carried out from the very beginning, but it is necessary to formulate a set of rules in accordance with the actual situation. But as you get more and more people, the probability of something going wrong increases dramatically, and then something goes wrong (Funny face), and if something goes wrong, go to CR.
CR mechanism how, how to CR an APP level (to participate in the development of dozens of scale) of the project, can continue to see, there is a special introduction to gerrit knowledge below.
Intermediate git theoretical knowledge and git practical skills
Above is about git popular science, as well as some thoughts on the problems encountered in the process of project development. I call the above section git Primer.
The following is an intermediate knowledge of Git
If you can use your git knowledge to solve all kinds of problems in the version control process, you are considered intermediate level.
Here I want to say one thing:
I use the command line form to operate Git, of course, there are many people use SourceTree VsCode WebStorm software to operate Git. I use the main command line. I also use VsCode.
My general usage rules are as follows:
Except that I need to read files, compare before and after versions of files, or view multiple historical versions, I use VsCode, all other operations are handled by the command line.
PS: If you want to play Git from the command line, you need to learn the basics of Linux. Recommended books:
“Birdman’s Private Linux Dishes: The Basics”
Because life continues, learning continues.
Intermediate theoretical knowledge of Git
Many people just remember the command operation of Git, but do not know the underlying reason for doing so. As a result, they do not know the reason for doing so, and finally they cannot have a more abstract and profound understanding of Git on a large knowledge level.
Now I will stand on the shoulders of others (not rework) and briefly analyze some intermediate theoretical knowledge of Git based on what I have learned.
Here I use a picture on the web to briefly summarize the principle of Git’s API level.
Then I will show you two git analysis diagrams (picture and text analysis) of Vamei:
The first picture:
The second picture:
The above three pictures are an API-level picture and two git principle analysis pictures of Vamei.
If you have a deep understanding of the above three pictures, you can feel the design idea and distinctive characteristics of Git from the pictures. If you can understand deeply, you can say that you have already mastered the intermediate theoretical knowledge.
But it doesn’t matter if you don’t understand it, I will briefly analyze the intermediate theoretical knowledge of Git.
What does git init do
To find out what git init does, we need to perform git init and then analyze the changes before and after it is executed.
We start with a new directory and initialize a new Git repository as follows:
// Create a new directory, use ls -a, there is nothing in itcd 0112-git-test
git init
cd .git/
ls -a
ls -l
Copy the code
git init
After the execution, the following figure is displayedIn the figure above, we can see the executiongit init
Command to create a new one in the current directory.git
Catalog, let’s go through it againls -l
You can see.git
All files and directories under the directory, including the permissions of these files and directories.
Instead of using other Linux commands on the command line to parse the body of the content, I’ll use code. Git =.git =.git =.git
We can infer several things from the picture
Git init = 0112-git-test; git init = 0112-git-test;
Refs /heads/master = ref: refs/heads/master = ref: refs/heads/master = ref: refs/heads/master
Git init is not an empty directory. Git init is not an empty directory. Such as:
Mkdir 0112-git-test-2 CD 0112-git-test-2 vi 1. TXT // Write the file and save it to exit git initCopy the code
Git init is not an empty directory. There is no change in the.git directory.
We will find that
The.git directory remains the same regardless of whether there is a file in the current directory or not, and the HEAD is set to the master branch by default.
Git init = master branch = master branch = master branch
Git init with git defaults to master.
Now let’s go ahead and execute GST on a non-empty directory, as shown below:
If we look at the arrow, we can see that the file is untrack, and nothing has changed with.git before and after we combined the git init command.
Can be derived:
1. TXT is not included in the version control system, untrack means not included in the version control system.
When analyzing.git directories, you must keep version control in mind.
Think time
Git Clone: What does Git Clone do? I’ll leave it to you to analyze.
Git directory as a whole
Git directory:.git directory:.git directory:.git directory:.git
Git init () git init ()
Git root contains many level 1 subdirectories and level 1 subfiles.
Use the hooks directory. Everything is connected, from naming to the latest react Hook feature. So there’s a bunch of files in there, like the pre-commit. Sample file, which is a sample file, and we’re going to code it like a sample file, and we’re going to get rid of the. Sample and say pre-commit, Git commit -m ‘XXX’ : git commit -m ‘XXX’ This is the lifecycle hook in Git.
Third: Look at the Objects directory, which is a directory for storing all kinds of data. Our project, no matter what form of data, images, audio, code, will be converted into a unified data format stored in the Objects directory.
For basic information about the Objects directory, see the following blog post about Git-Objects:
Git-Internals-Git-Objects
Fourth: The refs directory has heads and tags directories. And the subfile HEAD says ref: refs/heads/master, which is the branch git is currently pointing to.
How do you feel
I want you to think of the.git directory as a front-end project, for example you can think of the Objects directory as the dist directory in the front-end project. Any other analogy that helps you to understand it is a good analogy.
PS: This is the overall analysis, without in-depth introduction, it is good to have a general understanding.
What happened after Git add
When I add a file that is not in version control to the staging area with git add ·, I take a look at the change in the.git directory, as shown below:
We will notice that a directory named 60 has been added to the Object directory. There is a binary file in this directory. Git root directory has an index file, which is also a binary file.
From this, we can analyze several information:
First, the git add operation puts files that are not under version control into version control. At an intermediate level, the reason for this is that the.git directory has been substantially changed.
The second: git add actions will be generated in the objects directory subdirectory to 60, file called d4a4434d9218d600c186495057bb9b10df98ad a binary file.
Git add generates a binary file named index in the.git root directory.
We have a look at d4a4434d9218d600c186495057bb9b10df98ad the contents of the file?
Perform:
git cat-file -t 60d4a4434d9218d600c186495057bb9b10df98ad
Copy the code
The execution result is as follows:
Just one word, blob.
What is a blob?
A blob is a binary large object. So the way to think about it is, this file is a big binary object, OK, so let’s keep going.
Why is a file named with a string
Such as file d4a4434d9218d600c186495057bb9b10df98ad, don’t understand it doesn’t matter, continue to bring forward association, is thought of webpack file name after the packaging, can add a hash prefix in the front. There is a kind of suddenly enlightened feeling, I leave it to you to analyze.
Git add and blob and filename d4a4434d9218d600c186495057bb9b10df98ad associated
When git add is not executed, the directory is empty. When Git is added, a blob is added and a 40-character hash string is generated, and directories and files are hash represented. In other words:
Git add later became a blob object, is 60 d4a4434d9218d600c186495057bb9b10df98ad blobId.
See this you whether have a feeling again, remember a word:
Everything can be pushed.
Git commit -m ‘XXXXXX’ generates a commit object and commitId is a 40-bit hash character stored in the Objects directory.
There is an index file in the root directory. What is it?
Git add: git add: git add: git add: git add: git add: Git add: Git add: Git add
od -tx1 -tc -Ax index
Copy the code
As shown in the figure:
The string of data in the figure above is binary data in the index file.
Here let’s look at the red box I marked in the picture below.
As you can see, the index file contains a lot of information, such as 1.txt, 2.txt and TREE. There’s only so much information I can get at this point in terms of performance, and there’s got to be some kind of connection. The index file is a staging area.
You can read this official document directly to the conclusion:
Git-Internals-Plumbing-and-Porcelain
Think about time
Here are a few questions for you to think about:
If your project does not already have a commit, we will get the following error using git Stash in this case:
Why is this error reported?
Why take out the first two digits of a 40-character hash string as a directory?
What’s the logic behind this, is it algorithmic, is it for better performance, can the front end borrow this idea, or is it already there, what’s the idea?
Why does Git use binary data format to store data?
Think for yourself, there might be some interesting results.
How to understand Git Stash
Here I’ll show you how this happens in the.git directory through practice.
First I made a commit, and the project now has only one commitId, as shown below:
At this point, I use the following command:
TXT git add.Copy the code
Git add:
Take a look at the file indicated by the arrow above.
Click ORIG_HEAD can see is a string of 0991 ddc42dbda1176858b89008b8dece5f91093b controlled objects in the directory search, found that there are, we will use the following command
git cat-file -p 0991ddc42dbda1176858b89008b8dece5f91093b
Copy the code
We saw the tree, the tree also has a treeId, treeId to 33 b62884583995b8723d4d5ef75e44aa7d07fbf3
combininggit log
Take a look at the chart below:
Comparing the two figures, you can see that the hash value in the ORIG_HEAD file is equal to the hash value in the file location pointed to in HEAD. Words can not say too thoroughly, the latter self understand it.
What happens when you execute git Stash?
See below:
On the left is the contents of the index file that I put 2.txt into the staging area with git add. On the right is the contents of the index file in the staging area after I used git Stash. It can be seen that the index file before and after git Stash file is different.
See what I show you belowgif
Graph:
When I git commit, the commitId in the matser file in refs/heads is changed to the newly committed commitId, while the ORIG_HEAD is unchanged. The hash value of the file in the HEAD directory is the last commit in the current directory.
Check out this blog post:
Git staging principle
Git merge and Git rebase
Merge and rebase are probably the most famous questions in Git, and also the most explored knowledge points in the interview. For example, do you know the difference between merge and rebase? The list goes on and on.
Git rebase: Git rebase: git rebase: git rebase: git rebase: git rebase: git rebase: git rebase: git rebase
However, many tutorials are written too complicated, so I’ll use Rebase to give a popular explanation of what I personally understand.
For example, if the current branch is dev, then I execute:
git rebase master
Copy the code
How to understand the above command
One of the most important things is to knowrebase
It’s the consciousness of transformation.rebase master
Based onmaster
为 base
And then thedev
Branch patch hitmaster
After that, it’s generated in the process of typingcommitId
Is the newcommitId
,dev
The originalcommitId
Discarded, the timeline becomes a straight line.
Eventually, matser merged with my dev branch so that the latest commmitId was based on my latest commit (here’s my latest commit on the dev branch). So when I push, the code I submit becomes the benchmark.
Rebase is that simple.
Take a look at my two brief issues:
Let the concept of Git rebase end there
Git Merge: Git Merge
In the gitblob
commit
tag
tree
How are they strung together
In fact, this is a very key problem, many people do not clear the truth behind these words is what kind of beauty.
But I’m not going to make a wheel, because there are so many good articles, and I want to put one of the pictures up here, because it’s so classic.
The explanation is already in the text in the image, for example, knowing this will give you an idea of what we are doing when we tag the version. We can’t just be superficial about tagging, but we also need to know why we’re tagging. Only in this way can we know what we are and what we are.
End tag: github.com/godkun/git-…
Other bits and pieces of knowledge
COMMIT_EDITMSG file
This file contains the last information to be submitted locally
packed-refs
Clone all references to the warehouse
Intermediate practical skills of Git
I’ve distilled all of the Git operations I use to do version control with Git.
The purpose of my Git operations can be summarized as follows:
- The first purpose: to handle merges and resolve conflicts
- Second purpose: to submit code
- Third objective: to improve development efficiency
- Fourth objective: rational optimization
- The fifth purpose: when their own error operation, do quickly and correctly to deal with
- Sixth purpose: Help a colleague solve some of their problems
git
Operational problems
Below brief analysis above each purpose process some experience.
Handle merges and resolve conflicts
Git’s ability to handle merges and resolve conflicts trumps SVN. For example, when SVN processes a conflict, the warehouse is managed centrally and only remotely, so resolving the conflict is a submission race.
How did I personally manage conflicts and mergers in the project?
Following these steps, there will be almost no conflict resolution failures.
First, when I pull remote code, like execute
git pull origin dev
Copy the code
After the execution, I found a lot of conflict hints on the console. I checked and found that many of them were the conflicts of other people’s codes. How could I do that?
I will git reset –hard without hesitation
Rollback the merge, and I already know that this is not possible, but I can’t wait for someone else to modify the conflict. I would start by cutting a new branch from the current one
git checkout -b dev-backup
Copy the code
The dev-backup branch is used to save local code. And then at this point, I
git checkout dev
Copy the code
Switch to dev, and then what do I do? I’ll replace all the dev branch code with the remote dev branch:
git reset --hard origin/dev
Copy the code
At this point, my local dev branch has adopted all the remote dev branch code. At this point, I still need to incorporate my local changes, but at this point I can use a command:
git checkout dev-backup pages/xxxx
Copy the code
By using the above command, we can merge the code in the XXX directory or XXX file on the dev-backup branch into dev alone, and this part of the code is modified by me locally, so EVEN if there is conflict, I can quickly solve it. Then securely push the remote warehouse.
The above conflict resolution method, although simple, is the perfect way to solve all merge and conflict problems in Git version control.
Merge has always been a core node in a version control system, and it is important to understand how important merge and conflict resolution are in a version control system.
Submit code
This should not be a problem, but when you commit your local code to a remote repository, it’s a very important moment. Why do I say important? 😂 you’ve heard of a programmer who killed a colleague because he often git push-f. So be afraid, don’t matter, don’t panic, you just follow these principles:
- Don’t use it
git push -f
Unless you’re ready to stop living. 😂 - Don’t submit conflicts, check for conflicts before submitting.
- Write you
commit message
git commit
Before yougit status
Take a look and check if you’ve inadvertently changed any other files.
In fact, my personal feeling is that if it is my own business project, in addition to the first point, the second point and the fourth point, I need to pay attention to, like the fourth point, commit message, just happy, do not deliberately.
Improve development efficiency
Speaking of which, I’m sure you all have a few tips on how to speed up your version control with Git as you spend a lot of time with it. Let me summarize my own tips on how to improve your development efficiency.
Choose the alias that works best for you
GST stands for git status. Of course, you can also be more simple and happy.
Optimize your Stash
Using Stash well is also a simple and efficient way to improve development efficiency. I don’t know how to use it, but I have more details on it on Github. It is mainly for temporary storage, but most people have Git Stash
Reasonable optimization
When it comes to optimization, IN fact, I want to say that optimization is a relative concept, if the process of git control version optimization, I personally feel that I have not used much optimization, about the following:
- I use it occasionally
git rebase -i
Some of me I can’t even watchcommit
Process.
When you do something wrong, deal with it quickly and correctly
This is of course their stupid, accidentally messed up things, it is necessary to quickly solve their own wrong operation, how to solve, the idea is very simple:
In general, I follow the principle of removing bad operations from the remote warehouse as quickly as possible to minimize the impact on other coders.
For example, I can quickly back up my own code by local branch cutting, then switch back, quickly roll back my own error code, and then push it to the remote repository to solve the code conflict problem of the remote repository, and then I can continue to solve the problem of my own code locally.
Help colleagues with some of their problemsgit
Operational problems
In my opinion, if a project is very large and there are many participants, new coders will join in at any time, and you cannot guarantee that all the people will operate Git correctly. In this process, some people may conduct wrong git operation, and they cannot solve it by themselves, so they will seek help from other colleagues. I have also helped some of my colleagues. When I help other colleagues to deal with Git problems, I use a lot of commands, and sometimes I have to use some uncommon skills, such as re, filtering, etc., which will not be detailed here.
Actual combat in the process of some of their own perception
In my opinion, there is no need to complicate git operation during project development, and there is no need to pay attention to it. As the saying goes: it is great to be able to solve complex problems with simple operation. Therefore, the actual combat skills I introduced above can be said to have no lofty and profound skills. When the understanding is deep enough, simple operations can also ensure the orderly progress of the project.
Git Advanced — knowledge about Git that you probably didn’t know
Here’s an echo of what the article said at the beginning:
From elementary to intermediate to mehold
Don’t live high.
Why do I say I can’t hold it? Because I can’t handle it. But I went back and revisited C and C++ briefly to try to understand it.
Take a quick look at the Git source on Github
Clone your Git repository on Github.
Let’s take a look at the amount of git project code
Here I use a line of code analysis tool, CLOC, which can be installed by:
<! Brew install clocCopy the code
Once the installation is complete, run the following command in the.git directory:
cloc *.c *.h *.sh
Copy the code
As shown in the figure:
As can be seen from the figure, the current Git project on Github is composed of many languages, and the total number of lines of code in the master branch is about 500,000 (excluding PO files). The main languages are C SH (Bourne Shell) Perl C/C++ Header. I have several feelings:
First point: the amount of code is not very large, about 500,000 lines, and the Linux kernel such tens of millions of code level is still a gap, can only be considered a tool.
Second point: there are many languages involved, but the core languages are basically C, SH, C/C++ Header.
Now how do I analyze it.
Let’s start with dimension reduction
At present, due to the complexity of the directory, I want to look at the content of the first commit of Git project. Generally speaking, the amount of code in the first commit is relatively small. Here’s a screenshot I found on Github:
I went to the Git directory and executed
git checkout e83c5163316f89bfbde7d9ab23ca2e25604af290
Copy the code
Take a look at the code for the first commit, as shown below:
The command line:
VScode screenshots:
I was curious to take a look at the amount of code using CLOC, as shown below:
Surprised! Only 848 lines, is not a moment of confidence. Let’s start ending it!
As usual, I went to README to read the project description:
As shown in the figure:
The editor is Linux Torvalds
GIT – the stupid content tracker
“git” can mean anything, depending on your mood.
GIT GIT GIT GIT GIT GIT GIT
After READING the README, I learned the following:
All objects are named by their content, which is
approximated by the SHA1 hash of the object itself. Objects may refer to other objects (by referencing their SHA1 hash), and so you can build up a hierarchy of objects.
First point: All objects are named with their own content, identifying themselves with a SHA1 hash value. Objects can refer to other objects by referring to their SHA1 hash. So you can build a hierarchical object model.
Second point: the object content is compressed using Zlib, and SHA1 is always the hash of the compressed object content, not the original object content.
A “blob” object is nothing but A binary blob of data, and doesn’t refer to anything else. To put it simply: a bloB has no other properties, just the contents of a file.
The “current directory cache” is a simple binary file, which contains an efficient representation of a virtual directory content at some random
time. It does so by a simple array that associates a set of names, dates, permissions and content (aka “blob”) objects together. The cache is always kept ordered by name, and names are unique at any point in time, but the cache has no long-term meaning, and can be partially updated at any time.
Fourth: the current directory cache, which can be understood as a staging area, is also a binary file, which records the time, permissions, and object contents through a simple array.
# 5: SHA1 is used, so changes and content can be trusted.
README has plenty of information. That’s a lot of things.
The first COMMIT source code analysis
Here I will not make the wheel, found an article, the basic first commit source code of each file to explain the role of a more thorough.
Git source code
A brief analysis of the latest Git source code
performgit checkou master
Cut to the master branch
We can see from the picture that there are many, many things, do not want to analyze, then do not analyze, are more than 10,000 words, can not write. So happy to agree! Happy happy after the year, and then write a separate (hey hey hey).
Knowledge of gerrit principles
This principle knowledge is not said, simply speaking, is to build a Gerrit server, and then through the UI interface to carry out the code CR, CR passed, click Submit will synchronize the code to gitLab.
Gerrit combat summary
I was responsible for the implementation of Gerrit for the project, and solved various problems of my colleagues during the transition to gerrit. I have learned a lot about the process and operation of Gerrit while solving various problems. Here are some of the problems I have encountered in helping my colleagues transition to Gerrit.
Gerrit basic Settings
This will not say, basic like SSH authentication, remote Settings, email Settings, this I will not build wheels, according to the basic online tutorial.
Error: Change-Id missing when submitting gerrit
Problem description
This error is the most common one in the transition to Gerrit.
The error is shown below:
[8a5fCA6] missing change-id in commit message footer
CommitId = 8a5fCA6 commit with no change-id, so commit failed.
At the same time, we can see that there is a solution to this problem in the printed message. First execute:
gitdir=$(git rev-parse --git-dir); scp -p -P 29418 [email protected]:hooks/commit-msg ${gitdir}/hooks/
To perform:
git commit --amend
However, in the process of solving this problem, I found that the above tips sometimes do not succeed. I’ve come up with several scenarios, listed below.
The lack of Change – IdcommitId
Is commitId to which head points
In the case of head, this is the first commitId of git log. You can simply follow the instructions above.
If you execute git commit –amend, you can enter vi interface and save and exit without modifying anything to refresh the commitId value pointed to by head.
The lack of Change – IdcommitId
Not commitId that head points to
What if it’s not head, for example the sixth commitId is missing change-id? There are two ways to deal with this situation:
Git reset –soft
Use git reset –soft commitId to soft rollback the commit record to the commitId where the change-id is missing. Then you can do something like this:
git reset --soft 8a5fca6
git commit --amend
Copy the code
And then you can push. The fly in the ointment, however, is the soft rollback of other commits. If it is your own commit, then soft it directly. If not, you can use the second method below.
Git rebase -i commitId
Git rebase -i commitId git rebase -i commitId git rebase -i commitId git rebase -i commitId What we want to do here is to use this command to modify only the specified commit in the figure above, without affecting any other existing commit. The specific operation is as follows:
Git rebase -i commitId git rebase -i commitId git rebase -i commitId It is the commitId before commitId in the prompt. For example, git log
/ /... commit 7b7b7b7 commit avacaba commit 8a5fca6 commit godkun666Copy the code
So this commitId is Godkun666.
git rebase -i godkun666
Copy the code
Then enter the VI interface, as follows:
pick 8a5fca6 i am godkun1
pick avacaba I am godkun2
pick 7b7b7b7 I am godkun3
Copy the code
CommitId [8a5fca6] = reward; commitId[8a5fca6] = reward; This approach also tries to modify multiple Commitids that lack change-id at once. Once you save and exit, you can push directly. For information about Rebase-I, please do your own Google search.
I tried both, but it didn’t work
This kind of situation happened to a colleague. I tried the solutions to both cases, but they still failed. Then I looked carefully and implemented:
gitdir=$(git rev-parse --git-dir); scp -p -P 29418 [email protected]:hooks/commit-msg ${gitdir}/hooks/
Because I didn’t save the screenshot, I realized that hook is not directory, but it was not obvious in the process. After I checked the.git directory, I realized that the hooks were a file. This is not a directory, this is still pretty impressive, my first guess is that copying this command was incomplete, causing hooks to be generated. Then, after I deleted the hooks, I created a new hooks directory and re-executed the command.
commiter email address xxxx does not match your user account
This problem occurs because of the picturecommitId
The mailbox bound to it is incorrect. You need to set the correct email address first. After setting the correct email address, we will continue with other operations. I have summarized three ways to solve this problem:
Git reset –soft commitId rollback
Second, if the commitId is the point to head, git commit — Amend refresh the commitId.
3. If the commitId is head, reword the commitId with rebase -i.
Git-reset –soft if you want to be comfortable, then I will use git-reset –soft. If I want to be careful, THEN I will use the following two methods according to the conditions.
gerrit cannot merge and Submit including parents
Instead of building wheels, basic operation problems are covered in the following blog post:
How do I resolve Gerrit code conflicts
But without an opinion of your own, what’s the difference between that and salted fish?
So including parent and not merge
How to display:
Superficial reasons:
After the coder develops locally, it generates a commit and pushes it to Gerrit. The CRR will reject it according to the situation. If the coder rejects the local commit, but the coder does not cancel the local commit, the following series of commit will occur. Because the current commit depends on the previous ones. However, the previous commit did not agree. So that leads to a lot of CR problems.
Core reasons:
The commit timelines of coder and CR are inconsistent.
How to solve:
The core is to make the COMMIT timeline consistent
If the above problems have not occurred, how to prevent:
The first:
When coder successfully pushes the local commit to Gerrit, remember to reset it. If you are not sure, you can soft roll back stash and CR. If you pull it down and find no problem, you can discard stash.
The second:
After push, cut the new branch for backup, then cut back, and reset the local commit. In this way, there is no problem that the above diagram cannot be combined. When you pull, after CR, and you find that the code is correct, you can delete the backup branch.
What if these problems have already occurred?
Now the coder needs to kill local commits that have been abandoned by Gerrit abandon.
The first:
Git Clone
The second:
Cut a branch for backup and then cut back using:
git reset --hard origin/dev
Copy the code
Discard all local code and use all remote code. Then use Cherry Pick to add the commit you need for the backup branch to dev.
PS: Of course, these are only local coder to solve this problem.
The third:
Use rebase to make changes one by one or use git reset –soft to roll back many previous commits. It is not recommended to use the third method because the operation is highly demanding and error-prone.
how to make SourceTree push to Gerrit
Git repository code root
git config remote.origin.push refs/for/dev
Copy the code
how to make TortoiseGit push to Gerrit
This error occurs with push Gerrit, as shown below:
How do you solve it? Take a look at the screenshot below:
When pushing gerrit with a turtle, you should manually add refs/for/ to the remote
TortoiseGit pushes code to Gerrit
How to fast and efficient CR (Coder Review)
When you are asked to come to CR for code submitted by each product line, you will find it impossible to go to CR because you are not familiar with their code, how to CR, finally I decided to do:
If coder of each product line needs CR, please contact me. I have three principles in CR process:
The first principle: BY default, I believe that each product line should modify the code it is responsible for, that is, I believe coder to modify the code it is responsible for.
Second rule: I will pay close attention to whether each coder changes the other coder code, and if it changes, I will go to the private chat to ask why I do so.
The third principle: I will pay strict attention to whether each coder has changed the code of the common part, such as the login module. If it has changed, I will go to the private chat to ask why I want to do so.
Anything that does not comply with the three principles of appeal is abandon.
Git FAQ transfer
Send a link about git FAQ: git.wiki.kernel.org/index.php/G…
Refer to the link
- github.com/git/git
- Fabiensanglard.net/git_code_re…
- Nvie.com/posts/a-suc…
- Git-scm.com/book/en/v2/…
- Schacon. Making. IO/git/user – ma…
- Blogs.msdn.microsoft.com/devops/2018…
- aosabook.org/en/git.html is a great introduction to Git
- learngitbranching.js.org/This is an online experiment
git
The web site - Mirrors.edge.kernel.org/pub/softwar…
- Mirrors.edge.kernel.org/pub/softwar…
- Mirrors.edge.kernel.org/pub/softwar…
- Mirrors.edge.kernel.org/pub/softwar…
The above several articles about Git are I think very good articles, you can read, there will be a surprise.
note
- There are some knowledge is a point, this has written more than 12000 words, understand (laugh cry).
- There must be some mistakes in the article, welcome to discuss and point out.
- The article is a bit long and the reading experience may not be good, but I don’t have the heart to write separately, so let’s leave it at that.
Communication + Welfare
I have sorted out the git knowledge summarized in my daily work and study, and put the most commonly used ones on my GayHub in the form of issues. If you need them, you can click the following link:
Github.com/godkun/git-…
Nuggets series of technical articles summarized below, if you feel good, click a star to encourage, a star happy year (manual funny), you can also follow me a wave of gayhub, continue to output high-quality articles.
github.com/godkun/blog
I am the source terminator, welcome technical exchange.