1. Introduction to version control system

1.1 What is version control

The primary function of version control is to track file changes. It faithfully records when and who changed what in the file. Each time a file is changed, the version number of the file is increased. In addition to recording version changes, another important feature of versioning is parallel development. Software development is often a collaborative work of many people. Version control can effectively solve the problems of version synchronization and development communication between different developers, and improve the efficiency of collaborative development. The most common problem of fixing bugs in parallel development between different versions of software can also be effectively solved by branching and merging in version control.

Here is a simple example. All of you have written documents with Office Word. In the process of writing a document, you may need to delete a certain paragraph of the original document, but you are worried that this paragraph will be used again later. Later, the process might be repeated several times, and our document library might look something like this:

After a while, you may need to retrieve something that was deleted, but you can’t remember which document it was in, so you have to look at it one by one. If there are multiple versions of the document, this search process can be maddening. Also, you should never delete any of these different versions of documents, because you never know when you might need them again in the future.

The original code management approach is similar to the above case.

Disadvantages of traditional document/code management:

  • Version management chaos;

  • Version rollback is cumbersome.

  • Version merge difficulties;

  • . .

    The version control system is to solve the problem of similar to the above and invention, the basic function of the version control system is to record the change of each version, modified time, modifier, and so on, modify information, and then through the convenient tool in switching between different versions, merger, back, and so on.

    Therefore, in order to manage documents or code bases efficiently and quickly, it is necessary to move from “manual versioning” to automated versioning.

1.2 Distributed VS centralized

Currently, there are two major version-control architectures: distributed systems and centralized systems. What are they? What’s the difference?

  1. Centralized version control system:

    Let’s start with the centralized version control system. The version library is centrally stored in the central server, but when you work, you use your own computer, so you need to get the latest version from the central server, and then start work, finish work, and then push your work to the central server. The central server is like a library. To change a book, you must first borrow it from the library, then go home and change it yourself, and then put it back in the library.

    One of the biggest problems with centralized version control systems is that they need to be connected to the Internet to work. With poor bandwidth, submitting and updating large files can be very slow. In addition, the centralized version control system disaster recovery is poor, in case the central server hard disk data loss, the consequences are very serious.

  2. Distributed version control system:

    Distributed version control system and centralized version control systems is that the biggest difference between distributed version control system does not need to “central server”, every computer complete version of the system, are kept on the local submitted, back, branch of every code merge all don’t require the participation of the server, the local version of the system. Moreover, different versions on multiple different computers can be combined and updated over the network.

    The advantages of a distributed version system are obvious. First, it can work completely independently, without the involvement of a server. Second, it has high security, a computer data lost, can be recovered through other computers.

    In reality, a distributed version control system also requires a “central server,” but that server’s role is limited to facilitating data interaction.

    At present, the most popular centralized version control systems include SVN and CVS. Both of these systems are open source and free. Today, many people still use them.

    Git, the main character of this document, is a distributed version control system. It is simple, efficient and functional, and is the most popular version control system at present.

2. First taste of Git

2.1 Git Birth

Git’s origins are legendary. Linus invented Linux in 1991 and managed Linux code by hand until 2002. As Linux code grew exponentially, Linus was struggling. He chose BitKeeper, a commercial version of a distributed version control system, out of open source and personal quirks (he hated the low performance of centralized version control systems). Of course, BitKeeper is free for Linus to use.

Until 2005, the two were at peace, but an incident (when a Linux kernel developer tried to crack BitKeeper’s data protocol) infuriated BitKeeper and took back its free Linux license.

Instead of giving in to BitKeeper, Linus spent two weeks developing a distributed version control system in C, called Git. Within a month, the entire Linux code had been handed over to Git. Linus was a master.

Then, in 2008, with the rise of GitHub, Git took off and is now the most useful version management tool available.

2.2 install Git

Git supports all major operating systems. You must install Git before you can use Git.

  1. Linux system

    If you’re running Ubuntu, installing Git is fairly simple with one command:

    sudo apt-get install git;

  2. Windows system

    For Windows, you can download the appropriate Git version from the Git website and install it. The installation process is very simple.

    After the installation is complete, go back to the desktop, right-click and select Git Bash Here. Under normal circumstances, the Git interactive terminal will pop up.

After the installation is complete, simple configuration is required. Run the following command:

$ git config --global user.name "Your Name" 
$ git config --global user.email "[email protected]" 
Copy the code

The above two commands are mainly used to indicate their identity information, so that the code base can clearly see the relevant information of each submission.

The –global parameter of the git config command indicates that all git repositories on your machine will use this configuration. You can also specify a different username and Email address for each repository.

2.3 Creating a Git repository

A repository is a directory where you can add, delete, modify, and roll back all the files in the directory.

Creating a Git repository is as simple as two steps:

  1. Select an appropriate location and create an empty directory:

Note: If you are using Windows, make sure the directory names (including the parent directory) do not contain Chinese to avoid any unintelligsible problems.

  1. Create a Git repository by executing git init:

    Note: When learning Git, try not to use project code to do experiments, otherwise, improper operation will cause data loss.

    In two simple steps, a Git repository is created. Let’s add some files to the repository:

The above command creates a readme.txt file and adds some content.

Here's how to add the readme.txt file to the repository in two steps:Copy the code
  1. Add the readme.txt file to your git library using the git add command:
$ git add readme.txt 
Copy the code

You can use the Git add command multiple times if you have multiple files that need to be added to your Git repository.

  1. Commit to the repository using the git commit command:
$ git commit -m "wrote a readme file"
[master (root-commit) eaadf4e] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt

Copy the code

The -m option of the git commit command is used to indicate the description information about the current commit. The description information should be in a uniform format, which is beneficial to subsequent Bug management and version tracking.

3. Git local management

3.1 Submitting modifications

Now that you’ve added the readme.txt document, let’s go one step further and learn how to use the Git status command.

Open the readme.txt file and add the word distributed in the first line as follows:Now try using Git Status to check the state of the repository:Git status allows you to keep track of the status of your Git repository. The output above indicates that readme. TXT has been modified, but has not yet been stored in the Git repository.

Git diff allows you to view the current changes in the format of Linux kernel patches:Now we can commit our changes, using the same commands as git add and git commit. First, use git Add to add the readme.txt file:

$ git add readme.txt 
Copy the code

Use git status to check the current state of the repository:You can prepare readme.txt. Next, git commit the modification. ! [> [picture archived failure outside the chain, the source station might be hotlinking prevention mechanism, proposed to directly upload picture preserved (img – CFEmWlFM – 1616251474903) (media / 04789 ebe7e7808ae7341d292e0eb7ad6. PNG)]] (Img – blog. Csdnimg. Cn / 20210320225…

Again, by running git status, you can see that the repository has nothing to commit and that the working directory is clean.

If, after the git commit, you find that the commit instructions are not correct, you can modify the latest git commit by running the git commit –amend command:

  • Git log for recent commit records:

  • Run git commit –amend:

  • Amend the submission record as “Add distributed –amend” :

  • Git log to check the commit record again:

    According to the figure above, the last commit record has been modified.

Version 3.2 Rollback

Now that we’ve learned how to add files to the repository, we’ve learned how to commit changes. Let’s go ahead and modify readme.txt:

Git is a distributed version control system.
Git is free software distributed under the GPL.
Copy the code

Then, commit the changes:

In actual product development, we need to get into the habit of committing the changes to the repository when the code/documentation changes to a certain extent. This way, if subsequent code/document changes go wrong, or files are deleted by mistake, you can still recover with the most recent commit, which is called a rollback. Here’s how to do a version rollback.

  1. First, check the commit status of the repository using git log:

    As you can see, there are currently three COMMIT records. You can view the simplified version of the commit record with the –pretty=oneline parameter:

Note: As a reminder, you'll see a list of things like 1094adb... Git commit id is not 1,2,3... An increasing number, but a very large number calculated by SHA1 in hexadecimal, and the commit ID you see is definitely not the same as mine, take your own. Why does the COMMIT ID need to be such a long string of numbers? Because Git is a distributed version control system, we'll be looking at multiple people working in the same repository. If everyone uses 1,2,3... As a version number, that must be a conflict.Copy the code
  1. What if, for some reason, you want to roll back the repository to the “Add Distributed” commit?
  • First, Git must know which version it is. In Git, the current version is denoted by HEAD, the previous version is denoted by HEAD^, the previous version is denoted by HEAD^^, and the last 100 is denoted by HEAD~100. To go back to the previous version, run the following command:
$ git reset --hard HEAD^
Copy the code

Take a look at the contents of readme.txt, it is restored.

  • But what if, after a while, you suddenly find that you need to go back to the previous version? If you can find the commit ID of the previous version, you can use the git reset command to go back. Git provides Git reflog to record each time, so you can use Git reflog to find the commit ID of the previous version.

    The red box marks the last commit, and the first number is the COMMIT ID. Ok, run the following command to return the previous version:

$ git reset --hard 3b45c71
Copy the code

Git log (git log) :

  • Git’s version rollback is very fast because Git has an internal HEAD pointer to the current version. When you roll back to the version, Git simply points the HEAD back to the Append GPL:

    Point to Add Distributed:

3.3 Workspace and staging area

The concepts of workspaces and staging areas are often heard when working with Git administration versions. Understanding workspaces and staging areas can be helpful in understanding many of Git’s operations. The following table describes the two concepts.

  1. The workspace

    A workspace is the directory that we actually see, like Learngit is a workspace.

  2. The staging area

    There is a hidden directory in your workspace. Git. This directory is not your workspace, but the git repository.

    Git’s repository contains many things. The most important is a staging area called stage (or index), the first branch that Git automatically creates for us, the master, and a pointer to the master called HEAD.

We’ll talk about branching and HEAD later.

When you add a file to a Git repository, you do it in two steps:

The first step is to use Git Add to add the file, essentially adding the file changes to the staging area.

The second step is to commit your changes with Git Commit, essentially committing everything in the staging area to the current branch.

Because Git automatically creates a master branch for us when we create the Git repository, Git now commits changes to the master branch.

You can simply assume that all changes to the file that need to be committed are put into the staging area, and then commit all changes to the staging area at once.

Here’s a simple exercise to take a closer look at the concept of staging areas.

Open readme.txt and add the following line:

Git **is** a distributed version control system.

Git **is** free software distributed under the GPL.

Git has a mutable index called stage.
Copy the code

Then, in the workspace, create a new file LICENSE, the content of the file is arbitrary.

First, use git status to check the current state of the repository:

Git makes it very clear that readme.txt was modified and the LICENSE has never been added, so its status is Untracked.

Now, use git add twice. After adding readme. TXT and LICENSE, use git status to check again:

The state of the staging area now looks like this:

So, the git add command essentially puts all the changes that you want to commit into the Stage, and then, with git commit, commits all the changes from the Stage to the branch at once.

$ git commit -m "understand how stage works"
Copy the code

Now that the repository looks like this, the staging area is empty:

  1. Git diff comparison field

Git diff = git diff = git diff = git diff Git diff only compares the difference between the workspace and the staging area (last add), git diff –cached only compares the staging area and the repository, and Git diff HEAD — filename only compares the workspace and the repository (last commit). The three comparisons correspond to different commands.

3.4 Management Modification

Git performs better than other version control systems because it tracks and manages changes, that is, differences between versions, rather than simple files.

A change can be a new line, a new line, a new character, a new file, etc., all of which count as a change.

Here is a simple example of how Git manages changes.

  1. Open the readme.txt file and add the following line:
$ cat readme.txt

Git **is** a distributed version control system.

Git **is** free software distributed under the GPL.

Git has a mutable index called stage.

Git tracks changes.
Copy the code
  1. Then, use Git Add to add this change:

  1. Then, modify the readme.txt file again:
  $ cat readme.txt

Git **is** a distributed version control system.

Git **is** free software distributed under the GPL.

Git has a mutable index called stage.

Git tracks changes of files.
Copy the code

Submit, and then check the status:You can see that the second change is not committed.

When you use the Git add command, the first change in the workspace is put into the staging area, ready to commit. However, the second change in the workspace is not put into the staging area. So, Git commit is only responsible for committing the staging area change. The second change will not be committed.

Git diff HEAD — readme.txt to see the difference between the current version and the workspace:

As you can see, the changes are not committed to the repository. Use the git add and git commit commands again to commit the second modification to the repository.

3.5 Undoing The Modification

In the actual project development process, it is inevitable that mistakes will be made, for example, bugs are changed in the wrong location, code comments are written wrong, and so on. When a wrong modification occurs, it is necessary to undo the modification in a timely manner. The following describes the undo operations in different scenarios.

  1. Made changes to the contents of some files in the workspace and wants to discard the changes directly.

    Open readme.txt and add a line:

Git is a distributed version control system.

Git is free software distributed under the GPL.

Git has a mutable index called stage.

Git tracks changes of files.

Git add stupid chagnes.
Copy the code

Use the git status command to check the current state of the repository:

You’ll find git prompts to discard workspace changes using the :git checkout –<file> command. Then we execute the order:

git checkout — readme.txt

Running Git Status again shows that the workspace is clean and readme.txt is restored to the latest version of the repository.

  1. Not only did you change the contents of some files, but you also committed the changes to the staging area.

    Based on scenario 1, we use Git Add to commit readme.txt to the staging area, and use Git Status to check the current repository status:

Git reset HEAD <file\> can be used to move the changes in the staging area to the unstaged state (i.e. the workspace). Let's run this command and use Git status to check the current state:Copy the code

As you can see, the state of the readme.txt file is back to scenario 1, so the modifications can be discarded using the methods described in Scenario 1.

  1. Error fixes have been committed to the local repository.

    If you just commit the wrong changes to the local repository, you can roll back using the method described in section 3.2. However, if the changes have already been committed to a remote repository, nothing can be done.

3.6 Deleting a File

In practice, deleting some files is also a common operation, as shown in the following example.

First, add a file to the workspace and add it to the repository.

Normally, we are used to using RM or deleting files directly, so now delete them and check the current repository status:

Git is aware that the test. TXT file has been deleted, but the repository file has not been deleted. Git is aware that the test. TXT file has been deleted, but the repository file has not been deleted.

  1. Use git add/rm

    to update the changes to the staging area for commit.

  1. Use git checkout —

    to discard the workspace changes and restore the test.txt file you just deleted.

4. Remote warehouse

4.1 GitHub Experience

So far, we’ve learned a lot about the basics of Git. However, these features are not much different from previous centralized version control systems such as SVN.

Here’s one of Git’s killer features: remote repositories.

Git is a distributed version control system. The same Git repository can be distributed to different machines. How do you distribute it? In the beginning, there must be only one machine with an original repository, and later, other machines can “clone” the original repository, and every machine’s repository is the same, there is no precedence.

The actual work scenario is often like this, find a computer as a server, everyone else from the “server” warehouse clone to their own computer, and each of them push their own submissions to the server warehouse, but also pull others from the server warehouse. The “server” plays a role in this process, acting only as an intermediary for data sharing.

You can build your own Git server, so there’s no need to make a fuss in order to learn Git at this stage. You can learn how to use a remote repository by turning to GitHub, the world’s most famous Git repository hosting site.

Just sign up for an account at GitHub and you can start using GitHub’s services. However, since transfers between your local Git repository and GitHub repository are encrypted via SSH, a few Settings are required:

  1. Example Create an SSH Key. In the user’s home directory, check whether there is an. SSH directory. If there is, check whether there are id_rsa and id_rsa.pub files in this directory. If not, open the Shell (open Git Bash on Windows) and create an SSH Key:
$ ssh-keygen -t rsa -C"[email protected]"
Copy the code

You need to change the email address to your own email address, then press enter and use the default value. Since the Key is not used for military purposes, there is no need to set a password.

If all goes well, it can be found in the user’s home directory. SSH directory, there are two files id_rsa and id_rsa.pub, these two are the private Key pair, id_rsa is the private Key, can not be disclosed, id_rsa.pub is the public Key, you can trust to tell anyone.

  1. Log in to GitHub and follow these steps to add the public key to your GitHub account.

Fill in step 4 on meaningful Title, and will be/c/Users/Administrator /. Sshid_rsa. Pub file public key fill in step 5 is shown in the text box.

Click “Add SSH Key” and you can see that the Key has been successfully added to the GitHub account.

  1. Why does GitHub need an SSH Key? Git supports SSH, so GitHub knows your public key so it can be sure that only you can push.

    Of course, GitHub allows you to add multiple keys. Let’s say you have a number of computers and you submit at work and at home. Just add the keys of each computer to GitHub and you can push to GitHub on each computer.

4.2 Adding a Remote Repository

You’ve created learngit, opened a GitHub account, and configured your SSH Key. The next step is to create a Git repository on GitHub and synchronize the local repository with the GitHub repository, so that the GitHub repository can be a backup of the repository and the rest of the world can collaborate with you through the repository.

Creating a repository on GitHub is simple and takes just a few steps:

Select Learngit, click Create Repository to Create repository.

Currently, the Learngit repository on GitHub is empty. GitHub tells us that we can clone a new repository from the repository or associate an existing local repository with it, and then push the content from the local repository to GitHub.

Follow GitHub’s prompts and run the following command in your local Learngit repository:

$ git remote add origin https://github.com/flyunix/learngit.git
Copy the code

The yellow ones are GitHub accounts, which need to be replaced with your own account name. When added, the name of the remote library will be Origin, which is the default Git name. You can change it to something else, but the name origin is a clear indication of the remote library.

Synchronizing a local library to a remote library:

$ git push -u origin master
Copy the code

Git will not only push the contents of the local master branch to the new remote master branch, but also associate the local master branch with the remote master branch. This will make it easier to push or pull the remote master branch. You will be prompted to log in to GitHub. Enter your account and password to log in:

The following figure shows that the local and remote libraries have been synchronized.

After the push is successful, you can immediately see that the content of the remote library is the same as the local one on the GitHub page:

From now on, whenever a commit is made locally, you can run the following command:

$ git push origin master
Copy the code

Push the latest changes to the local master branch to GitHub.

4.3 Cloning a Remote Repository

Section 4.2 describes how to associate local libraries with remote libraries on GitHub. This section describes how to clone a remote library on GitHub.

  1. Go to GitHub and create a new repository called GitSkills.

Note that **Initialize this repository with a README, ** this will automatically add a README file to the repository.

Now that the remote library is ready, we can use Git Clone to clone a local library:

$git clone [email protected]:flyunix/gitskills.git
Copy the code

Change the Git repository address to your own and go to the gitskills directory to see if there is already a readme.md file:

In fact, GtiHub gives more than one address. You can also visit github.com/flyunix/git…

4.4 Setup and use of Git server

Considering the difficulty of using GitHub for remote repository experiments, we can set up a Local area network Git server ourselves. At present, there are many Git server software on the market, but the fastest way to set up a Git server is to install a Linux system with SSH and Git, especially Ubuntu or Debian system, with a few simple apt commands.

4.4.1 Logging In to the Git Server Remotely

At present, I have an Ubuntu virtual machine ready and can use putty to connect to the virtual machine over SSH. The basic configuration information of the VM is as follows:

  • Access address :192.168.2.35:6666

  • SSH Login account: my name in pinyin initials, such as LHL

  • SSH login password :123(the same for all accounts)

    For example, log in to the LHL using Putty.

After configuring the IP address and port number of the SSH server, click "Open".Copy the code

Enter the account: LHL, press Enter, enter the password :123, press enter, as shown in the following figure.

4.4.2 Setting up remote warehouse

This section explains how to create a Git repository.

  1. First, log in to your account over SSH.

  2. Collect all need to log in to the user’s public key, is their own id_rsa. Pub file, id_rsa. Production can refer to the pub file, put all the public key into the/home/git /. SSH/authorized_keys file (first need to create the file), in a row.

  3. ~/ SRV /learngit. Git

git init --bare learngit.git
Copy the code

Git creates a bare repository. A bare repository has no workspace, because the repository on the server is purely for sharing, so users are not allowed to log in directly to the server to change the workspace, and the repository on the server usually ends in.git. Then, change the owner to your account name, such as LHL:

chown -R lhl:lhllearngit.git
Copy the code

In this way, the remote repository is created.

Git server port 6666 is not the standard SSH 22, so the command is a little different. Change the username to your own.

$ git remote add origin ssh:/ / [email protected]:6666 / home/LHL/SRV/learngit git
Copy the code

4.4.3 Cloning a remote Repository

Now that we have created our own repository, we can clone the repository from the Git server to the local repository in the same way that we clone the remote repository. Note that Git server port 6666 is not the standard SSH 22, so the clone command is slightly different:

$git clone ssh:/ / [email protected]:6666 / home/LHL/SRV/learngit git
Copy the code

5. Git branch management

5.1 Why do I Need Branches

Branches are an important concept in version management systems. Different branches in a repository are completely independent of each other until the merge date. So, in practice, what is the role of branches?

Let’s say you’re trying to develop a new feature that will take two weeks to complete, and you write 50% of the code in the first week. If you commit it immediately, because the code hasn’t been written yet, the incomplete code base will cause people to stop working on it. If you wait until all the code has been written and commit again, you run a huge risk of losing your daily progress.

Now that we have branches, we don’t have to be afraid. You create a branch of your own, no one else can see, continue to work on the original branch, and you work on your own branch, commit as much as you want, until the development is finished, and then merge on the original branch, so that it is safe, and do not affect the work of others.

But Git branches are different. You can create, switch, and delete branches in less than a second! It doesn’t matter if your repository is 1 file or 10,000 files.

5.2 Branch Creation and Merging

In version rollback, you already know that every commit, Git strings them together into a timeline, and that timeline is a branch. As of now, there is only one timeline, and in Git this branch is called the master branch. HEAD technically doesn’t point to commit, it points to master, and master points to commit, so HEAD points to the current branch.

Git uses the “master” branch to point to the latest commit and the “HEAD” to point to the “master” branch. Git uses the “master” branch to point to the latest commit and the “HEAD” branch to point to the “master” branch.

With each commit, the master branch moves a step forward, so that the line of the master branch gets longer and longer as you commit:

When you create a branch, for example, dev, Git creates a new pointer called dev and points to the same commit as master, and then points the HEAD to dev to indicate that the current branch is on dev:

As you can see from the figure above, Git creates a branch very quickly, because nothing changes in the workspace except adding a dev pointer and changing the HEAD point.

From now on, however, changes and commits to the workspace are made to the dev branch. For example, after a new commit, the dev pointer moves forward one step, while the master pointer stays the same:

If our work on dev is done, we can merge dev into master. How to merge Git? The easiest way to do this is to direct the master to the current commit of the dev and complete the merge:

So Git merges branches fast! Change the pointer, the workspace content also unchanged!

After merging the branches, you can even delete the dev branch. Deleting the dev branch is to delete the dev pointer. After deleting it, we are left with a master branch:

The following example demonstrates the specific command operation.

First, create the dev branch, and then automatically switch to that branch:

The git checkout command is created and switched with the -b parameter.

Then, look at all branches in the repository with Git Branch, where the current branch is preceded by an *.

Now, let’s make some changes on the dev branch, for example, add a line to readme.txt:Commit this change on the dev branch:

Now that the work on the dev branch is complete, switch to the master branch and view the contents of the readme.txt document:

As you can see, the changes you just made on the dev branch do not affect the master branch. Now let’s merge the master and dev branches:

The git merge command is used to merge a branch into the current branch. After the merge, look at the contents of readme.txt and see that it is exactly the same as the latest commit of the dev branch.

Note the fast-forward information above, Git tells us that the merge is in “fast-forward mode”, i.e. the merge is directed directly to the current commit of dev, so the merge is very Fast.

Of course, not every merge can be fast-forward, and we’ll talk about other merges later.

After merge, you can safely delete the dev branch:

Git Branch also shows that there is only one branch left in the system.

Because it’s so fast to create, merge, and delete branches, Git encourages you to use branches to complete a task, merge them, and then delete them. This is just as effective as working directly on the master branch, but the process is safer.

5.3 Conflict Resolution

In practice, a Git-based code development model might have multiple people working on different branches, and branch merging is not always smooth, and there are always conflicts to deal with.

Here is a simple example of how to resolve repository conflicts during development.

  1. Preparing a New branch, Feature1:

    Change the last line of readme.txt to:

Creating a **new** branch is quick **AND** simple
Copy the code

Submit changes on Feature1:

  1. Switch to the master branch:

On the master branch change the last line of the readme.txt file to:Copy the code
Creating a **new** branch is quick & simple
Copy the code

Commit this change on the master branch:

Now both the Master branch and Feature1 branch have new submissions, which look like this:

In this case, Git cannot perform a “quick merge”. Instead, Git tries to merge the changes together.

Git tells you that there is a merge conflict and you need to resolve it manually and then resubmit. Git status tells you if there are conflicting files.

Readme.txt file:

Git use <<<<<<<, =======, >>>>>>> to mark the contents of different branches, we modify the following after saving:

Creating a new branch is quick and simple.

Now the Master and Feature1 branches look like this:

Git log with arguments can also be used to see branch merges:

$ git log --graph --pretty=oneline --abbrev-commit
Copy the code

Finally, delete the Featuer1 branch.

5.4 Branch Management Policies

Git usually merges branches in Fast forward mode if possible, but in this mode, the branch information is lost when the branch is deleted. If Fast forward mode is disabled, Git generates a new COMMIT at the merge, so that the branch history can be seen.

Git merge –no-ff git merge

First, still create and switch the dev branch:

Modify the readme.txt file and commit a new commit:

To prepare to merge dev branches, note the –no-ff argument, which disables Fast Forward:

$ git merge --no-ff -m "merge with no-ff" dev
Copy the code

Since this merge will create a new COMMIT, add the -m argument to the commit description.

After the merge, we use git log to look at the branch history:

$ git log *--graph --pretty=oneline --abbrev-commit*
Copy the code

As you can see, without the Fast forward mode, the merge looks like this:

In practical development, we should follow a few basic principles for branch management:

First of all, the master branch should be very stable, that is, it should only be used for new releases, and you should not work on it.

Where do you work? All work is done on the dev branch, that is, the dev branch is unstable, and at some point, such as the 1.0 release, the dev branch will be merged into the master and the 1.0 release will be made on the master branch.

Each of you and your friends will work on the dev branch, each of you will have your own branch, and every now and then you will merge into the dev branch.

So, the branch of teamwork looks like this:

5.5 the Bug branch

Bugs are a common occurrence in software development. Bugs need to be fixed, and branches are so powerful in Git that every bug can be fixed with a new temporary branch, which can be merged, and then deleted.

When you receive an assignment to fix a bug code-named 101, it’s natural to want to create a branch issue-101 to fix it, but wait, the work currently in progress on Dev hasn’t been committed yet:It’s not that you don’t want to submit it, it’s just that the work is halfway done and you can’t submit it yet, and it’s expected to take another day to complete. But what if you have to fix the bug in two hours?

Fortunately, Git also has a stash feature that allows you to “stash” your current work site so you can work on it later when the site is restored:

Now, with Git Status, your workspace is clean (unless there are no files managed by Git), so you can safely create branches to fix bugs.

First, determine which branch to fix the bug on. Assuming you need to fix the bug on the master branch, create a temporary branch from the master:

Git is free software… Git is a free software… , and submit:

When the fix is complete, switch to the Master branch, complete the merge, and finally remove the issue-101 branch:

Great, it took only 5 minutes to fix the bug that was supposed to take 2 hours! Now it’s time to get back to work on the Dev branch!

The workspace is clean. Where did you save the work site? Use the git stash list command to see:

The work site is still there, Git has stash content somewhere, but there are two ways to restore it:

One is to restore using git Stash apply. However, after restoring, the stash contents are not deleted. You need to delete them using git stash drop.

Another way is to use the Git Stash Pop and remove the stash contents as you recover:

If you look at the Git Stash list again, you won’t see any stash contents.

You can stash multiple times. To recover, first look at the git stash list and then retrieve the specified stash using the command:

$ git stash apply stash@{0}
Copy the code

5.6 Feature Branch

In software development, there is always an endless amount of new functionality to be added.

When adding a new feature, you certainly don’t want to mess up the main branch because of some experimental code. Therefore, it is better to create a new feature branch for development every time a new feature is added, and then merge it and delete it at last.

Now you finally have a new assignment: developing a new feature code-named Vulcan that is planned for the next generation of starships.

So ready to develop:

After 5 minutes, the development is complete:

Switch back to Dev and prepare to merge:

$ git checkout dev
Copy the code

If all goes well, the feature branch and bug branch will be similar, merged and then deleted.

But!

At this time, received superior order, due to lack of funds, the new function must be cancelled!

It was in vain, but the branch containing the classified information had to be destroyed on the spot:

Now let’s force delete:

You can see the deletion succeeded!

5.7 Multi-party Collaboration

When you clone from a remote repository, Git automatically matches the local master branch to the remote master branch, and the default name of the remote repository is Origin.

To view information about a remote repository, use git remote or git remote-v:

The above shows the address of origin that can be grabbed and pushed. If you do not have push permission, you will not see the push address.

  1. Push branch:

    Push branch pushes all local commits on that branch to the remote library. Git pushes the branch to the remote branch of the repository:

To push another branch, such as dev, change it to:Use Git Branch -A to view all branch information for your local and remote repositories. However, local branches do not have to be pushed remotely, so which branches should be pushed and which should not?

  • The master branch is the main branch, so it must be synchronized with the remote branch at all times.

  • The dev branch is the development branch on which all team members work, so it also needs to be synchronized remotely;

  • The bug branch is only used to fix bugs locally, so there’s no need to push it remotely unless the boss wants to see how many bugs you fix each week.

  • Whether the feature branch is pushed to remote depends on whether you are working with your partner on it.

  1. Grab a branch:

    When working together, everyone pushes their changes to the Master and Dev branches.

    Now, to simulate one of your friends, clone it on another computer (be sure to add the SSH Key to GitHub) or in a different directory on the same computer:

$ git clone [email protected]:flyunix/learngit.git
Copy the code

When your partner clones from a remote repository, by default, your partner only sees the local master branch. Git branch = git branch

Now, if your friend wants to develop on the dev branch, he must create the remote origin branch locally, so he uses this command to create the local dev branch:

$ git checkout -b dev origin/dev
Copy the code

Now, he can continue to make changes on dev, and then push the dev branch remote from time to time:

Your friend has already pushed his commit to the Origin /dev branch, and you happen to have made changes to the same file and tried to push:

Git pull the latest commit from origin/dev, merge it locally, resolve the conflict, and push it again:If git pull fails, there are two ways to fix it: one is to specify a link between the local dev branch and the remote origin/dev branch.

$ git branch *--set-upstream-to=origin/dev dev*

Branch 'dev'支那set** up **to** track remote branch 'dev'**from**'origin'.
Copy the code

Another is the git pull origin dev command to pull again.

Pull:

This time, git pull is successful, but merge conflicts need to be resolved manually, and the way to resolve conflicts is exactly the same as in branch management. After solving, submit and push:

Push succeeded!

Therefore, the working mode of multi-person collaboration usually looks like this:

  1. First, you can try to push your own changes with git push origin <branch-name>.

  2. If the push fails, you need to use git pull to merge the remote branch before your local update.

  3. If there is a conflict with the merge, resolve the conflict and commit locally;

  4. Git push origin <branch-name> <branch-name>

    If no tracking information is displayed in git pull, the link between the local branch and the remote branch is not created. Use the git branch — set-upstreamto <branch-name> origin/<branch-name> command.

    This is how multi-person collaboration works, and once you get used to it, it’s pretty easy.

5.8 Deleting a Remote Branch

If you run the git branch -a command to learn the collaborating time, you can discover that the remote branch is deleted.

6. Label management

6.1 What is a Label

When we release a version, we usually start with a tag in the repository so that we uniquely identify the version at the time of the tag. Whenever you take a version of a tag in the future, you take a version of the history of that tagged moment. So, the tag is also a snapshot of the repository.

Git’s tag is a snapshot of the repository, but it’s actually a pointer to a commit. But branches can be moved, tags can’t be moved), so creating and deleting tags is instantaneous.

Git has a Commit, so why introduce tags?

“Please package the release from Last Monday, commit 6A5819e…”

“A jumble of numbers to find!”

If there is another way:

“Please package and release the version from Last Monday, version number is V1.2.”

“Ok, just follow Tag V1.2 for COMMIT!”

So tag is a memorable and meaningful name that is tied to something called COMMIT.

6.2 Creating a Label

Tagging in Git is very simple. First, switch to the branch where you want to tag:Then, you can type git tag <name> to create a new tag and use git tag to see all the tags:

The default label is on the most recent commit. Sometimes, if you forget to label, for example, it’s Already Friday, but the labels that should have been typed on Monday are not typed, what can you do?

The method is to find the commit ID of the previous commit and type it:

For example, to label the add merge commit whose COMMIT ID is DFd5ef0, type:

$ git tag v09. dfd5ef0
Copy the code

Git tag = git tag

Note that the tags are not listed chronologically, but alphabetically. Git show <tagname>

As you can see, V0.9 does appear on this add Merge commit.

You can also create a label with a description, using -a to specify the label name and -m to specify the description:

Git show <tagname>

Note: The tag is always linked to a COMMIT. If the commit appears on both the master and dev branches, you will see the tag on both branches.

6.3 Managing Labels

If the label is mistyped, you can also delete it:

The created labels are stored locally and are not automatically pushed to remote locations. As a result, mistyped labels can be safely removed locally.

To push a tag to a remote location, use the git push origin <tagname> command:Or, push all the local tags that haven’t been pushed to the remote at once:If the tag has already been pushed to a remote location, deleting the remote tag is a little more cumbersome, first deleting it locally. Then, delete from the remote. The delete command is also push, but in the following format:

7. Git customization

7.1 File Neglect

Sometimes you have to put files in your Git working directory but can’t commit them. For example, a configuration file that holds a database password. That’s not gonna be nice for an ocD kid.

It’s easy to solve this problem by creating a special.gitignore file at the root of your Git workspace and filling in the name of the file you want to ignore.

Instead of writing the.gitignore file from scratch, GitHub already has a variety of configuration files for us, and we just need to combine them and use them. All configuration files can be viewed online directly: github.com/github/giti…

The rules for ignoring documents are:

  1. Ignore files automatically generated by the operating system, such as thumbnails.

  2. Ignore compile-generated intermediate files, executables, etc., i.e. if one file is automatically generated from another file, there is no need to put the automatically generated files in the repository, such as.class files from Java compilation;

  3. Ignore your own profiles that contain sensitive information, such as passwords.

    Here’s an example:

    Here are some of the most common things to ignore in C projects:

# Prerequisites
*.d

# Object files
*.o
*.ko
*.obj
*.elf

# Linker output
*.ilk
*.map
*.exp

# Precompiled Headers
*.gch
*.pch

# Libraries
*.lib
*.a
*.la
*.lo

# Shared objects (inc. Windows DLLs)*.dll *.so *.so.* *.dylib # Executables *.exe *.out *.app *.i*86 *.x86_64 *.hex # Debug files *.dSYM/ *.su *.idb *.pdb #  Kernel Module Compile Results *.mod* *.cmd .tmp_versions/ modules.order Module.symvers Mkfile.old dkms.conf # My configurations: ... .Copy the code

– Add your own configuration information to Git, the last step is to commit. Gitignore to Git, complete! Git status = “working directory clean”;

Sometimes you want to add a file to Git, but you can’t because the file is ignored by.gitignore:

For example, if we add a test.o file, because the.gitignore file contains files with the.o suffix, test.o would normally not be added to the repository.

If you do want to add this file, you can use -f to force it into Git:

Git check-ignore: git check-ignore: git check-ignore:Git tells us that line 5 of the.gitignore rule ignores the file, so we know which rule to fix.

7.2 Configuring aliases

Git supports nicknames for commands to simplify memorization. For example, let’s replace git status with the alias st:

$ git config –global alias.st status

Give it a try, using git ST, as follows:

Of course, there are other shorthand commands. Many people use co for checkout, ci for commit, and br for branch:

$ git config --global **alias**.co checkout $ git config --global **alias**.ci commit $ git config --global **alias**.br  branchCopy the code

Later submissions can be abbreviated as:

$ git ci -m "bala bala bala..."
Copy the code

The –global parameter is a global parameter, meaning that these commands are available in all Git repositories on this computer.

In the Undo changes section, we know that the git reset HEAD file command unstages the changes in the staging area and puts them back into the workspace. Since this is an unstage operation, you can configure an unstage alias:

$ git config –global alias.unstage ‘reset HEAD’

When you type in a command:

$ git unstage test.txt

What Git actually does is:

$ git reset HEAD test.txt

7.3 Configuration File

When configuring Git, adding –global will only work for the current user; otherwise, it will only work for the current repository.

The location of each repository’s local configuration file is stored in the repository’s. Git /config file:

The alias is right after [alias]. To delete the alias, delete the corresponding line.

Gitconfig (/c/Users/Administrator) : /c/Users/Administrator

You can also modify the file directly by configuring the alias. If the change is wrong, you can delete the file and reconfigure it through the command.

Submodule management

In the usual project development process, you may have met the requirements that the current project want to introduce another library, the library can be a third party library or library is one of your own development framework, and the maintenance of you want to separate the two projects, namely, to maintain the current project and import the independence of the library between the respective git repository. In this case, you may need to use knowledge of Git submodules.

Git submodules allow you to introduce one or more Git libraries as subdirectories within your Git project, and each one is completely independent, which brings great flexibility and convenience to the development and maintenance of each Git repository. The following is a specific description of the specific use of the module. In the demonstration, the Gitee code hosting platform will be used to store the remote code base.

8.1 Creating a Submodule

Submodules exist as subdirectories in an existing Git repository. They can be created in a very simple way. For example, if your current project is a gitLearn repository, you can clone it to your local directory by running the following command:

git clone [email protected]:flynix/git-learn.git
Copy the code

Now add the gitSubModule submodule to the current code base with the following command:

git submodule add [email protected]:flynix/git-sub-module.git
Copy the code

You can see that a git-sub-module subdirectory has been added to the current code base, which is a clone of the local git-sub-Module code base. You can use the git status command to modify the current workspace.The.gtiModules file is used to store information about the current submodule. If there are more than one submodule, there will be multiple records corresponding to it.How does Git view the contents of submodules in the current project? This can be seen with the git diff –cached command.

As you can see, Git treats the git-sub-module directory as a whole sub-module. When you are not in that directory, Git does not track its contents, but rather treats it as a specific commit in the sub-module repository. You can see better submodule output using git diff –cached –submodule.Ok, commit the current repository changes.Note the pattern 160,000 recorded by git-sub-module. This is a special pattern in Git that essentially means that you record a commit as a directory, rather than as a subdirectory or a file.

Finally, push the local changes to the remote code base.

8.2 Cloning a submodule

Now that the Git-Learn code base is a code base that contains submodules, how do you clone code that contains submodules?

We clone through [email protected]:flynix/git-learn. After you clone git-learn, you can only see an empty git-sub-module directory. Then you need to use the following two commands to pull the contents of the sub-module:

 git submodule init;

git submodule update;
Copy the code

Git submodule init is used to initialize the local configuration file.

The Git SubModule Update pulls all the data from the project and checks out the appropriate commits listed in the parent project.

The git-sub-module subdirectory is now in the same state as when it was committed.

You can add the –recurse subModules parameter to Git Clone, and it will automatically initialize and update every submodule in the repository, including nested submodules that may exist.

8.3 Maintaining Submodules

8.3.1 Pulling out the Remote End for Modification

If the remote end of a submodule has a new commit, how do you update the remote commit in the local code base?

For example, add a new helloWorld file to the git-sub-module and submit it to the remote end.

Then, enter the Git-sub-module and merge the remote commit via git fetch and Git merge.

Git diff –submodule (git diff –submodule)You can set the diff. Submodule to “log” to make this the default behavior.If you don’t want to update the remote submodule in the subdirectory, you can use the git submodule update –remote command. Git will go to the submodule and grab and update it.

If you commit at this point, then you will lock the submodule to new code when someone else updates it. That is, if you pull the git-learn library with the –recurse — submodules argument git clone, it will pull the latest submodule code information.

By default, this command assumes that you want to update and check out the master branch of the submodule repository. But you can set it to whatever branch you want. For example, if you want the git-sub-module sub-module to track the “devs” branch of the repository, you can either set it in the.gitModules file (so that others can also track it) or just in the local.git/config file. Let’s set it in.gitModules:

git config -f .gitmodules submodule.git-sub-module.branch devs
Copy the code

This is to use Git Status to display the status of the workspace.

If you set the git config status.submodulesummary 1 option, you can see more details about the submodules.

You can run Git diff to see the changes in the current workspace and even the commit record of the submodule.

When running git submodule update –remote, git attempts to update all submodules by default, so if there are many submodules, you can pass the name of the one you want to update.

8.3.2 Collaboration among project members

Another project already has a git-learn project locally, and he can use git pull to pull the latest commit from the remote, as follows:

First, add a newfile, newfile, to the git-sub-module and push it to the remote code base. Currently, there are two Git-learn codebases :git-learn and git-lear-vs, which pull the latest git-sub-module commit information from git-learn.

And push the current commit to the remote server.

Using git pull to pull the latest commit in git-lear-vs, execute Git status to see that the submodule information has been changed, but not updated.

By default, the git pull command recursively grabs changes in submodules, as shown in the output from the first command above. However, it will notupdateSon module. This can be seen with the git status command, which displays the submodule “already. In addition, the Angle brackets (<) on the left indicate new commits, indicating that they have been logged in git-learn but not checked out in the local Git-sub-module. To complete the update, you need to run git Submodule update:

8.3.3 Working on submodules

Working on submodules works much the same way as a regular Git repository. Note here that, by default, when we run git SubModule Update to grab changes from the submodule repository, Git will get these extensions and update the files in the subdirectory, but the replacement subrepository is left in a state that replaces “wandering HEAD”. This means that even if you commit changes to a submodule, those changes will most likely be lost the next time you run git SubModule Update if there is no working partition to track the changes. A few additional steps are required to track these changes in the submodule. In order to modify the submodule normally, the following two steps need to be completed:

  1. Check out the appropriate work branch in the submodule.

  2. Run the git submodule update – remote command to obtain the latest commits from the remote end and merge them into the local branch.

If the changes in the uncommitted submodule are synchronized to the upstream submodule commit, the message will be displayed, the local changes will be overwritten, and the synchronized update will terminate.If the modification of the local submodule conflicts with the previous submodule, the conflict can be resolved in the normal conflict resolution mode.

Q&A

1. fatal: in unpopulated submodule XXX

For example, the following prompts appear:

fatal: in unpopulated submodule hello.c

Because hello.c was cloned from another third-party library, the above error message appears.

The appendix

1. Reference links:

Pro Git in Chinese

Liao Xuefeng Git tutorial

2. Windows Notepad related pits

Never use the Notepad that comes with Windows to edit any text files. The reason is that the Microsoft notepad team used a very stupid behavior to save files encoded in UTF-8. They cleverly added 0xefbbbf (hexadecimal) at the beginning of each file, and you get a lot of weird problems. For example, the first line of a web page might display a “? It is clear that the correct program will report syntax errors as soon as it is compiled, etc., are brought by the stupid behavior of Notepad. Suggest you download Notepad++ instead of notepad, not only powerful, and free! Remember to set the default encoding for Notepad++ to utf-8 without BOM:

Git Warning: LF will be replaced by CRLF in readme.txt

The first problem is that different operating systems use different newline characters. Here are the newline characters for the three major operating systems:

Uinx/Linux uses LF to indicate the next line (LF: LineFeed, Chinese meaning is a newline);

Dos and Windows use CarriageReturn + LineFeed CRLF to indicate the next line (CRLF: CarriageReturn LineFeed, Chinese meaning is CarriageReturn LineFeed);

The Mac OS uses the CarriageReturn (CR) to indicate the next line (CR: CarriageReturn).

In Git, you can use the following command to show which way your Git currently treats newlines

$ git config core.autocrlf
Copy the code

When “true”, “false”, or “input” is true, Git will treat all files you add as text and convert the ending CRLF to LF, while checkout will convert the LF to CRLF again.

When false, line endings do not change and the text file stays as it was.

When it is input, Git converts CRLF to LF when it is add, and LF when it is check. Therefore, it is not recommended to set this value in Windows operating systems.

The solution:

Setting the core. Cascade LF to false will fix that, but if you and your partner work only on Windows or Linux, then that’s fine, but if there’s a cross-platform effect, then you need to consider that.

But when core messenger LF is true, there’s another concern: when you upload a binary, Git may mistake it for a text file and change your binary, too.

PS: Attach a command to change the cascade LF to true for example:

$ git config --global core.autocrlf true
\The #true position puts the result you want for the messenger LF, true, false or input.
Copy the code