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:

  • gitIt can be developed offline,svnCan’t offline
  • gitTo deal withmergeThe 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,VCSThe three countries have not yet decided the final outcome, perhapsSVNWill continue to play a role in important projects, butgitEventually 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:

  1. Take a branchmergeWhen it gets to another branch, it mishandles it.
  2. 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 daycommit“And you know.
  3. Use it without thinking it throughresetThis horrible command to operate on otherscodercommit.
  4. resetThe 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 initAfter the execution, the following figure is displayedIn the figure above, we can see the executiongit initCommand to create a new one in the current directory.gitCatalog, let’s go through it againls -lYou can see.gitAll 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 belowgifGraph:

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 knowrebaseIt’s the consciousness of transformation.rebase masterBased onmasterbaseAnd then thedevBranch patch hitmasterAfter that, it’s generated in the process of typingcommitIdIs the newcommitIddevThe originalcommitIdDiscarded, 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 treeHow 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:

  1. The first purpose: to handle merges and resolve conflicts
  2. Second purpose: to submit code
  3. Third objective: to improve development efficiency
  4. Fourth objective: rational optimization
  5. The fifth purpose: when their own error operation, do quickly and correctly to deal with
  6. Sixth purpose: Help a colleague solve some of their problemsgitOperational 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:

  1. Don’t use itgit push -fUnless you’re ready to stop living. 😂
  2. Don’t submit conflicts, check for conflicts before submitting.
  3. Write youcommit message
  4. git commit Before yougit statusTake 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:

  1. I use it occasionallygit rebase -iSome of me I can’t even watchcommitProcess.

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 problemsgitOperational 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 meholdDon’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 masterCut 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 – IdcommitIdIs 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 – IdcommitIdNot 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 picturecommitIdThe 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

  1. github.com/git/git
  2. Fabiensanglard.net/git_code_re…
  3. Nvie.com/posts/a-suc…
  4. Git-scm.com/book/en/v2/…
  5. Schacon. Making. IO/git/user – ma…
  6. Blogs.msdn.microsoft.com/devops/2018…
  7. aosabook.org/en/git.html is a great introduction to Git
  8. learngitbranching.js.org/This is an online experimentgitThe web site
  9. Mirrors.edge.kernel.org/pub/softwar…
  10. Mirrors.edge.kernel.org/pub/softwar…
  11. Mirrors.edge.kernel.org/pub/softwar…
  12. 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

  1. There are some knowledge is a point, this has written more than 12000 words, understand (laugh cry).
  2. There must be some mistakes in the article, welcome to discuss and point out.
  3. 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.