Getting started with git (must see)

getting started with git

Introduction to Git


What is "version control"? Why should I care about it? Version control is a system that records changes in the content of one or several files for future reference to specific version revisions. In CODE CHINA, we do version control on the files that save the software source code, but in fact, you can do version control on any type of file.

If you are a graphic or web designer, you may need to save all revisions of a certain picture or page layout file (this may be a feature you are eager to have), using a version control system (VCS) is a wise choice. With it, you can roll back selected files to the previous state, or even roll back the entire project to the state at a certain point in the past. You can compare the details of file changes and find out who modified which place in the end , to find out what caused weird issues, who reported a bug when, and so on. Using a version control system usually also means that even if you change, delete, or delete files in the entire project in one go, you can still easily restore it to the original state. But the additional workload is minimal.

Next, we will review the history of the development of version control systems.

Version control system development can be divided into three stages:

  • local version control system
    • Many people are accustomed to saving different versions by copying the entire project directory, and perhaps changing the name and adding the backup time to show the difference. The only advantage of doing this is simplicity, but it is extremely error-prone. Sometimes it will confuse the working directory, accidentally write the wrong file or overwrite the unexpected file.
      In order to solve this problem, people have developed many kinds of local version control systems a long time ago, and most of them use some kind of simple database to record the previous update differences of files.
      One of the most popular is called RCS, and it can still be found on many computer systems today. The working principle of RCS is to save the patch set on the hard disk (the patch refers to the changes before and after the revision of the file); by applying all the patches, the contents of each version of the file can be recalculated.
  • Centralized version control system
    • Then people encountered another problem, how to make developers on different systems work together? Thus, the centralized version control system (Centralized Version Control Systems, referred to as CVCS) came into being. Such systems, such as CVS, Subversion, and Perforce, have a single centrally managed server that saves revisions of all files, and people who work together connect to this server through clients to take out the latest files or commit renew. This has been standard practice for version control systems over the years.
      This approach brings many benefits, especially compared to old-fashioned on-premises VCS. Now everyone can see to some extent what everyone else on the project is doing. Administrators can also easily control the permissions of each developer, and managing a CVCS is far easier than maintaining a local database on each client.
      But this also has an obvious disadvantage, that is, the single point of failure of the central server. - If there is an hour of downtime, no one can submit updates during this hour, and they will not be able to work together - If the disk where the central database is located is damaged and there is no proper backup, you will undoubtedly lose all data— —includes the entire change history of the project, leaving only the individual snapshots that people keep on their respective machines.
      A similar problem exists with local version control systems, as long as the history of the entire project is kept in a single location, there is a risk of losing all historical updates.
  • Distributed version control system
    • So the Distributed Version Control System (DVCS) came out. In such systems, such as Git, Mercurial, Bazaar, and Darcs, the client does not only extract the latest version of the file snapshot, but mirrors the code repository completely, including the complete history. In this way, if any server used for collaborative work fails, it can be restored with any mirrored local warehouse afterwards. Because every clone operation is actually a complete backup of the code repository.
      Not only that, but many of these systems can be specified to interact with several different remote code repositories. In this way, you can collaborate with people from different working groups on the same project. You can set different collaboration processes according to your needs, such as a hierarchical model workflow, which was not possible in the previous centralized system.

The Birth of Git

Next, let's take a look at the story of Git's birth.

Background on the birth of Git

Like many great things in life, Git was born in a time of great disruption and innovation.

Linus created the open source Linux in 1991. Since then, the Linux system has continued to develop and has become the largest server system software. During 1991-2002, volunteers from all over the world sent the source code files to Linus through diff, and then Linus himself merged the code manually.

You might be thinking, why didn't Linus put the Linux code in the version control system? Isn't there free version control systems like CVS and SVN? Because Linus firmly opposes CVS and SVN, these centralized version control systems are not only slow, but also must be networked to use. There are some commercial version control systems, although they are easier to use than CVS and SVN, but they are paid, which does not match the open source spirit of Linux.

Linus completed Git in two weeks

By 2002, the Linux system had been developed for ten years, and the large code base made it difficult for Linus to continue to manage it manually. The entire project team began to use a proprietary distributed version control system BitKeeper to manage and maintain the code, BitKeeper BitMover, the owner of BitMover, also licenses the Linux community to use this version control system for free. Later, BitMover discovered that someone in the community was trying to crack the BitKeeper protocol, so BitMover took back the free use right from the Linux community.

This forced the Linux open source community (especially Linux creator Linus Torvalds) to develop its own versioning system based on lessons learned when using BitKeeper. They set several goals for the new system:

  • speed
  • simple design
  • Strong support for non-linear development models (allowing thousands of parallel development branches)
  • fully distributed
  • Ability to efficiently manage very large-scale projects like the Linux kernel (speed and data volume)

So, Linus spent two weeks writing a distributed version control system in C, which is Git! Within a month, the source code of the Linux system has been managed by Git!

Git grows

Since its inception in 2005, Git has matured and improved, while maintaining a high degree of ease of use, it still retains the goals set at the beginning. It's fast, great for managing large projects, and has an incredible non-linear branching system. Git quickly became the most popular distributed version control system. Especially in 2008, the GitHub website was launched. It provides Git storage for open source projects for free. Numerous open source projects began to migrate to GitHub, including jQuery, PHP, Ruby, etc.

git install

Git installation Before you can start using Git, it needs to be installed on your computer. Even if it is already installed, it is best to upgrade it to the latest version. You can install it through software packages or other installation programs, or download source code to compile and install. Below, we will introduce how to install Git on different operating systems.

Install on Windows

The method of installing Git on Windows is as follows:
Install using the official version
The official version can be downloaded from the official Git website. Open https://git-scm.com/download/win and select the corresponding version.

Install on macOS

There are several ways to install Git on a Mac.
The easiest way is to install Xcode Command Line Tools. On Mavericks (10.9) or higher, try running the git command for the first time Terminalin . bash $ git --version If you have not installed the command-line developer tools, you will be prompted to install them. If you want to install a newer version, you can use the binary installer. The officially maintained macOS Git installer can be downloaded from the official Git website at https://git-scm.com/download/mac .

Install on Linux

The basic Git tools are installed on Linux with a binary installer, which can be installed using the basic package management tools included with the distribution. For Fedoraexample , if you're using it (or a closely related RPM-based distribution like RHEL or CentOS), you can use dnf: bash $ sudo dnf install git-all If you're on a Debianbased distribution like Ubuntu, use apt: bash $ sudo apt install git-all To learn more Multiple choices, Git official website has installation steps on various Unix distribution systems, the URL is https://git-scm.com/download/linux .

Git environment configuration

Well, when you have completed the installation of Git, then we need to make some necessary environment configurations for Git. Normally, Git only needs to be configured once per computer, and the configuration information is preserved when the Git program is upgraded. You can modify them at any time by running git configthe command .
git config
Git comes with git configa tool to help set configuration variables that control Git's appearance and behavior. Next, let's learn how git configto configure user information through commands

Configure username and email address

After installing Git, the first thing to do is to set up your username and email address. This is important because every Git commit uses this information, and it's written to every commit you make, immutable:

git config --global user.name "李老师"
git config --global user.email [email protected]

Again, if --globalthe option , the command only needs to be run once, because Git will use that information for everything you do on the system afterwards.

When you want to use a different user name and email address for a specific project, you can configure it by running the command without --globaloptions .

check configuration

If you want to check your configuration, you can use git config --listthe command to list all the configurations that Git can find at that time.

git config --list

Git color scheme

So far, we have configured user.nameand user.email, in fact, Git has many more configurable items. For example, telling Git to display colors will make the output of the command look more eye-catching:

git config --global color.ui true 

Git display colors
This way, Git will display different colors appropriately, such as git statusthe file name will be marked with color after using the command.

Git ignore file configuration

Sometimes, you have to put certain files in the Git working directory, but you cannot submit them, such as configuration files that save database passwords, etc., which will be displayed every time. In this case, you can ignore git statusspecial Untracked files ...files .gitignorepractically It is very convenient to solve this problem. First, we create a special .gitignorefile , and then fill in the names of the files to be ignored. Git will automatically ignore these files every time it is submitted.
Rules for ignoring files
In daily use, we generally don't need to edit files from scratch .gitignore. There are already various ready-made configuration files, which can be used only by combining them. All configuration files can be browsed directly online: https://codechina.csdn.net/codechina/gitignore
The principle of ignoring files is:

  1. Ignore files automatically generated by the operating system, such as thumbnails, etc.;
  2. Ignore the intermediate files, executable files, etc. generated by compilation, that is, if a file is automatically generated by another file, then the automatically generated file does not need to be put into the version library, such as the .class file generated by Java compilation;
  3. Ignore your own configuration files with sensitive information, such as passwords.

Forcibly add ignored files

git add App.class 
The following paths are ignored by one of your .gitignore files: App.class Use -f if you really want to add them. 

If you really want to add the file, you can -fforce it to Git with:

git add -f App.class 

Or if you find that there may be .gitignorea problem with the writing, you need to find out which rule is wrong, you can use git check-ignorethe command to check:
check ignore rules

git check-ignore -v App.class
.gitignore:3:*.class App.class

Git will tell us that .gitignorethe rule on line 3 ignores the file, so we can know which rule should be revised.
Sometimes, when we write a rule to exclude some files:
bash # 排除所有.开头的隐藏文件: .* # 排除所有.class文件: *.class
but we find that .*this rule .gitignorealso excludes, and App.classneeds to be added to the repository, but is *.classexcluded by the rule.
Add exception rules
At this time, although it can be git add -fadded by force, we suggest that you can add two exception rules: the wording is
bash # 排除所有.开头的隐藏文件: .* # 排除所有.class文件: *.class # 不排除.gitignore和App.class: !.gitignore !App.class to exclude the specified file from .gitignorethe rule !+文件名, so just add the exception file.

Configure git log -1

Configure one git lastto display the last commit message:

git config --global alias.last 'log -1' 

In this way, use git last to display the latest commit:

git last 
commit 4aac6c7ee018f24d2dabfd01a1e09c77612e1a4e (HEAD -> master) 
Author: Miykael_xxm 
Date: Tue Nov 17 11:14:15 2020 +0800 
branch test 

configure git lg

git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" 

These are some common configurations of git.

Git configuration file

These custom Git configuration files are usually stored in the warehouse .git/configfile:

global configuration file

cat .git/config

The alias is just behind [alias]. To delete an alias, just delete the corresponding line. The current user's Git configuration file is placed in a hidden file in the user's home directory .gitconfig:

git uses

Create a directory

Initialize warehouse

git init

In an instant, Git built the warehouse and told you that it was an empty warehouse (empty Git repository). At the same time, there was an additional .git directory under the current directory. This directory is used by Git to track and manage the repository. If you do not Seeing the .git directory is because this directory is hidden by default, and you can see it with the ls -ah command.

Clone an existing repository

git clone <url>

Custom local warehouse name

Of course, if you want to customize the name of the local warehouse when cloning the remote warehouse, you can specify a new directory name through additional parameters:

git clone https://codechina.csdn.net/codechina/help-docs mydocs

This does the same thing as the previous command, but the target directory name is changed to mydocs.

Git supports a variety of data transfer protocols. The above example uses the https:// protocol, but you can also use the git:// protocol or use the SSH transport protocol, such as user@server:path/to/repo.git.

edit and add files

Next, let's try to edit a readme.txt file in the prepared Git warehouse, the content is as follows:

bash Git is a version control system. Git is free software.

Next, we can add the newly created readme.txt to the Git repository with two commands:

The first step is to tell Git to add the file to the warehouse with the command git add:

git add readme.txt

Execute the above command, if there is no display, it means the addition is successful.

Commit changes to the repository

In the second step, use the command git commit to tell Git to submit the file to the warehouse:

git commit -m "wrote a readme file" 
[main aac23f0] wrote a readme file
 1 file changed, 1 insertion(+)
 create mode 100644 readme.txt

Here is a brief explanation of the git commit command. The input after -m is the description of this submission. You can enter any content. Of course, it should be meaningful, so that you can easily find the change record from the history.

After the git commit command is executed successfully, it will tell you:

1 file changed: 1 file was changed (our newly added readme.txt file)
1 insertions: A line of content was inserted (readme.txt has a line of content)
Why does Git need add and commit to add a file in two steps? Because commit can submit many files at one time, you can add different files multiple times, such as:

git add file1.txt $ git add file2.txt file3.txt
git commit -m "add 3 files."

View the current status changes of the Git repository

We have successfully added and submitted a readme.txt file, let us continue to modify the readme.txt file and change it to the following:

bash Git is a distributed version control system. Git is free software.

Now, run the git status command to see the result:

git status 
On branch master Changes not staged for commit: (use "git add ..." to update what will be
 committed) (use "git checkout -- ..." to discard changes in working directory)
modified:   readme.txt
no changes added to commit (use "git add" and/or "git commit -a") 

Note that git restore and git checkout have the same effect, now the latest is using git restore

The git status command allows us to keep track of the current status of the warehouse. The output of the above command tells us that readme.txt has been modified, but there is no modification ready to be submitted.
insert image description here

Compare changes

Although Git tells us that readme.txt has been modified, it does not tell us what the specific content of the modification is. If it happened to be modified last week, when we come to work on Monday, we can’t remember how to modify readme.txt last time. At this time, we need to use the git diff command to see what has been modified compared to the last temporary storage:

Run the git diff command

git diff readme.txt 

insert image description here

As the name implies, git diff is to view the difference, and the displayed format is the common diff format of Unix. As you can see from the above output, we added a distributed word in the first line.

Comprehensive operation

After knowing what changes have been made to readme.txt, it will be more at ease to submit it to the warehouse. Submitting changes and submitting new files is the same two steps. The first step is git add:

git add readme.txt

Also no output. Before executing the second step of git commit, let's run git status to see the status of the current warehouse:

git status
On branch master Changes to be committed: (use "git reset HEAD ..." to unstage)

modified:   readme.txt

git status tells us that the changes to be submitted include readme.txt, and the next step is to submit with confidence:

git commit -m "add distributed" 
[master e55063a] add distributed 1 file changed, 1 insertion(+), 1 deletion(-)

After submitting, let's use the git status command to see the current status of the warehouse:

git status 

insert image description here

Git tells us that there are currently no changes that need to be committed, and that the working directory is clean (working tree clean).

view log

If you feel that the output information is too much and you are dazzled, you can try adding the --pretty=oneline parameter:

git log --pretty=oneline

insert image description here

Every time a new version is submitted, Git will actually automatically string them into a timeline. If you use the visualization tool or the git lg command introduced in the git custom configuration, you can see the timeline of the commit history more clearly:

git lg

insert image description here

As an excellent version control system, Git allows us to view the records of each commit. In daily work, we can modify the contents of the Git warehouse at any time. Whenever you feel that the file has been modified to a certain extent, you can "save a snapshot". This snapshot is called commit/submit in Git. Once you mess up the file or delete the file by mistake, you can restore from the latest commit and continue working instead of losing all the results of several months of work.

git log

In Git, we can view all commit records through the git log command:
insert image description here

The git log command shows the commit log from the most recent to the furthest, we can see 2 commits, the most recent one is add distributed, and the earliest one is write a readme file.

Git fallback

At this time, suppose we need to roll back readme.txt to the previous version, which is the version written a readme file, how do we do it?

First of all, Git must know which version the current version is. In Git, HEAD is used to represent the current version, which is the latest submission e55063a. The previous version is HEAD^, and the previous version is HEAD^^, of course, 100 versions up It is easier to write 100 ^ than count, so it is written as HEAD~100.

Now, if we want to roll back the current version add distributed to the previous version write a readme file, we can use the git reset command:

git reset --hard HEAD^
HEAD is now at aac23f0 wrote a readme file

Now let's see if the content of readme.txt is the version write a readme file:

cat readme.txt 
Git is a version control system. Git is free software.

Sure enough, it has been restored to the version originally written a readme file.

The version rollback speed of Git is very fast, because Git has a HEAD pointer pointing to the current version internally. When you roll back the version, Git just changes HEAD from pointing to add distributed:

HEAD pointer movement records

┌────┐ │HEAD│ └────┘ │ └──> ○ add distributed │ ○ wrote a readme file 改为指向wrote a readme file: ┌────┐ │HEAD│ └────┘ │ │ ○ add distributed │ │ └──> ○ wrote a readme file

Then, by the way, the files in the workspace are updated. So which version number you let HEAD point to, you will locate the current version.

Git reset

Now, you reverted to a certain version, turned off the computer, and regretted it the next morning. What if you want to restore to the new version? What should I do if I can't find the commit id of the new version?

Fortunately, Git provides a command git reflog to record each of your commands. When you use git reset --hard HEAD^ to roll back to the version written a readme file, and then want to restore to add distributed, you can use git reflog The command finds the commit id of add distributed.

git reflog
aac23f0 (HEAD -> main) HEAD@{
    
    0}: reset: moving to HEAD^
ca5f957 HEAD@{
    
    1}: commit: add distributed
aac23f0 (HEAD -> main) HEAD@{
    
    2}: commit: wrote a readme file
148737e (origin/main, origin/HEAD) HEAD@{
    
    3}: clone: from https://github.com/xxxx-sky/AudioGPT

From the above output, we can see that the commit id of add distributed is ca5f957. Now, we can switch to the latest version through git reset --hard ca5f957.

Workspace and staging area

One difference between Git and other version control systems such as SVN is the concept of a staging area.

Working Directory

It is the directory you can see on your computer. For example, my learngit folder is a workspace:
insert image description here

Repository

The workspace has a hidden directory .git, which is not considered a workspace, but a Git repository.

There are a lot of things stored in the Git repository, the most important of which is the temporary storage area called stage (or index), the first branch master that Git automatically created for us, and a pointer to the master called HEAD .
insert image description here

As mentioned earlier, when we add files to the Git repository, it is executed in two steps:

The first step is to use git add to add the file, which is actually to add the file modification to the temporary storage area; the
second step is to use git commit to submit the changes, which is actually to submit all the contents of the temporary storage area to the current branch.
Because when we created the Git repository, Git automatically created the only master branch for us, so now, git commit is to submit changes to the master branch.

You can simply understand that all the file modifications that need to be submitted are placed in the temporary storage area, and then all the modifications in the temporary storage area are submitted at one time.

Now, let's try it, first make a modification to readme.txt, such as adding a line:

bash Git is a distributed version control system. Git is free software distributed under the GPL. Git has a mutable index called stage.

Then, add a LICENSE text file in the workspace.

First check the status with git status:

git status 
On branch master Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory)

modified:   readme.txt
Untracked files: (use "git add ..." to include in what will be committed)

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

Git tells us very clearly that readme.txt has been modified, and the LICENSE has never been added, so its status is Untracked.

Now, use the command git add twice, after adding readme.txt and LICENSE, check it again with git status:

git status 
On branch master Changes to be committed: (use "git reset HEAD ..." to unstage)

new file:   LICENSE
modified:   readme.txt

Now, the status of the staging area becomes like this:
insert image description here

Therefore, the git add command actually puts all the changes to be submitted into the staging area (Stage), and then executes git commit to submit all the changes in the staging area to the branch at one time.

git commit -m "understand how stage works" 
[master 599dbdb] understand how stage works 2 files changed, 2 insertions(+) create mode 100644 LICENSE

Once committed, the workspace is "clean" if you haven't made any changes to it:

git status 
On branch master nothing to commit, working tree clean

Now the version library has become like this, and there is nothing in the temporary storage area:

insert image description here

Undo changes

git commit --amend

It's important to understand that when you're patching the last commit, you're not doing it by replacing the old commit in place with the improved commit. In effect, it doesn't appear in the repository's history as if the old commit never existed.
The most obvious value of patching commits is the ability to slightly improve your last commit without cluttering your repository history with "ah, forgot to add a file" or "minor fix, typo" commit messages.

 git commit -m 'initial commit' 
 git add forgotten_file 
 git commit --amend

unstaged file

  1. git reset HEAD
  2. git restore --staged

There are two known methods, the current git add is prompted after adding to the cache area is the second method
insert image description here

git reset method:
insert image description here

git restore method:
insert image description here

Undo changes to a file

git checkout method:
insert image description here

git restore method:
insert image description here

delete/restore files

Delete files locally
insert image description here

git add test.txt 
git commit -m "remove test.txt"

insert image description here

Another way to delete files:

git rm

Manually delete the file first, and then use git rm and git add to have the same effect.

Restore files (deleted locally but committed files)

git checkout -- 

insert image description here

branch management

Almost all version control systems support branching in some form. Using branches means that you can separate your work from the main line of development so that it does not affect the main line of development. In many version control systems, this is a slightly inefficient process - often requiring an exact copy of the source code directory to be created. For large projects, this process can take a lot of time.

Some people call Git's branching model its "nirvana feature", and it is precisely because of this feature that Git stands out from many version control systems. Why is Git's branching model so good? The way Git handles branches is incredibly lightweight, creating new branches is almost instantaneous, and switching between branches is just as easy. Unlike many other version control systems, Git encourages the frequent use of branching and merging in your workflow, even many times a day. Understand and master this feature, and you will realize how powerful and unique Git is, and it will really change the way you develop since then.

Introduction to git branches

To really understand how Git handles branches, we need to review how Git stores data.

We learned earlier that Git saves not file changes or differences, but a series of snapshots at different times.

When committing, Git will save a commit object (commit object). Knowing the way Git saves data, we can naturally think that the commit object will contain a pointer to a snapshot of the temporary content. But more than that, the commit object also contains the author's name and email address, the information entered when committing, and a pointer to its parent object. The commit object generated by the first commit has no parent object, the commit object generated by the normal commit operation has one parent object, and the commit object generated by merging multiple branches has multiple parent objects,

To illustrate this more vividly, let's assume that we now have a working directory that contains three files that will be staged and committed. The temporary storage operation will calculate the checksum for each file, then save the current version of the file snapshot to the Git warehouse (Git uses blob objects to save them), and finally add the checksum to the temporary storage area for submission:

git add readme.txt test.md LICENSE 
git commit -m 'The initial commit of my project'

When using git commit to commit, Git will first calculate the checksum of each subdirectory (only the project root directory in this example), and then save these checksums as tree objects in the Git repository. Subsequently, Git will create a commit object, which in addition to the information mentioned above, also contains a pointer to the tree object (project root directory). In this way, Git can reproduce the saved snapshot when needed.

Now, there are five objects in the Git repository: three blob objects (holding file snapshots), a tree object (recording the directory structure and blob object index), and a commit object (containing pointers to the aforementioned tree objects and all commits information).
![Insert picture description here](https://img-blog.csdnimg.cn/aae00e9b629d4cea982d3b3d6d6211e0.png )

Submit again after making some changes, then the generated submission object this time will contain a pointer to the last submission object (parent object).
![Insert picture description here](https://img-blog.csdnimg.cn/3920b183c236437eb231cfb01ca94e8c.png )

Git branches are essentially just mutable pointers to commit objects. Git's default branch name is master. After multiple commit operations, you actually have a master branch pointing to the last commit object. The master branch is automatically moved forward with each commit.
![Insert picture description here](https://img-blog.csdnimg.cn/a8c311fab4034fcd9a0d99b7b8c3750b.png )

create branch

Git will string each commit in the warehouse into a timeline, and this timeline is a branch. In Git, each warehouse will have a main branch, the master branch. Strictly speaking, HEAD does not point to the submission, but to the master, and the master points to the submission. Therefore, HEAD points to the current branch.

At the beginning, the master branch is a line. Git uses master to point to the latest submission, and then uses HEAD to point to master, so that the current branch and the submission point of the current branch can be determined:

git-br-initial

Every time you commit, the master branch will move forward one step, so that as you continue to commit, the line of the master branch will become longer and longer.

When we create a new branch, such as dev, Git creates a new pointer called dev, which points to the same submission as the master, and then points HEAD to dev, which means that the current branch is on dev:

insert image description here

You see, Git creates a branch very quickly, because apart from adding a dev pointer and changing the HEAD pointer, the files in the workspace have not changed!

However, from now on, the modification and submission of the workspace is aimed at the dev branch. For example, after a new submission, the dev pointer moves forward one step, while the master pointer remains unchanged:

insert image description here

If our work on dev is complete, we can merge dev into master. How does Git merge? The easiest way is to directly point the master to the current commit of dev, and the merge is completed:

insert image description here

So Git merge branches are also fast! Just change the pointer, and the content of the work area will not change!

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

insert image description here

That's amazing, can you see that some commits were made through the branch?

Let's start the actual combat.

Create a branch:

git branch 分支名

Create and switch to branch:

git checkout -b 分支名
git switch -c 分支名

switch branch:

git checkout 分支名
git switch 分支名

Query branch:

git branch

merge branch

git merge 分支名

The git merge command is used to merge the specified branch into the current branch.
After git merge dev
merges the dev branch into main, the content added in dev can be seen in the main branch.

Delete branch:

git branch -d 分支名

branch management strategy

Usually, when merging branches, Git will use Fast forward mode if possible, but in this mode, after deleting the branch, the branch information will be lost.

If you want to forcibly disable the Fast forward mode, Git will generate a new commit when merging, so that the branch information can be seen from the branch history.

Forcibly disable Fast forward

--no--ff
git merge --no-ff -m "merge with no-ff" dev

Using this mode git log can see the branch merge information, otherwise you can't see it

insert image description here

bug branch

Git also provides a stash function, which can "store" the current work site, and continue to work after restoring the site later:
git stash
cannot handle untracked objects
insert image description here

Just the scene above, resulting in 2 stash

Create the issue-101 branch, delete the branch after fixing the bug
insert image description here

Go back to the working branch and restore the site. If you use
the git stash apply stash@{0} command, you need to use
git stash drop to delete the stash content, or directly use git stash pop to delete the stash content while restoring.
insert image description here

Usage of git stash pop:

This branch can only be stashed after it is added to the temporary storage area
insert image description here

insert image description here

After returning to the working branch, use the git stash pop command, you can see that the git stash list is not echoed, so there is no need to delete the content of the stash, because it has already been deleted.
insert image description here

Use of the cherry-pick command

For multi-branch codebases, it is a common requirement to move code from one branch to another.

There are two situations at this time. In one case, you need all the code changes of another branch, then use git merge. Another situation is that you only need some code changes (certain commits), then Cherry pick can be used.

git log query to the commitHash of a specific commit
insert image description here

The function of the git cherry-pick command is to apply the specified commit to other branches.

git cherry-pick commitHash

The above command will apply the specified commitHash to the current branch. This will result in a new commit on the current branch, although of course their hashes will be different.
Cherry pick supports transferring multiple commits at once.
The argument to the git cherry-pick command, not necessarily the hash of the commit,Branch names are also possible, which means to transfer the latest commit of the branch.

git cherry-pick feature

The above code means to transfer the latest commit of the feature branch to the current branch.

git cherry-pick transfers multiple commits

Cherry pick supports transferring multiple commits at once.

git cherry-pick <HashA> <HashB>

The above command applies two commits, A and B, to the current branch. This generates two corresponding new commits in the current branch.

If you want to shift a series of consecutive commits, you can use the following convenience syntax.

git cherry-pick A..B

The above command can transfer all commits from A to B. They must be placed in the correct order: commit A must be before commit B, otherwise the command will fail without error.

Note that with the above command, commit A will not be included in the cherry pick. If you want to include commit A, you can use the syntax below.

git cherry-pick A^..B

git cherry-pick configuration item

Common configuration items for the git cherry-pick command are as follows.

-e,--edit: 打开外部编辑器,编辑提交信息。
-n,--no-commit: 只更新工作区和暂存区,不产生新的提交。
-x: 在提交信息的末尾追加一行cherry picked from commit ...,方便以后查到这个提交是如何产生的。
-s,--signoff: 在提交信息的末尾追加一行操作者的签名,表示是谁进行了这个操作。
-m parent-number,--mainline parent-number: 如果原始提交是一个合并节点,来自于两个分支的合并,那么 Cherry pick 默认将失败,因为它不知道应该采用哪个分支的代码变动。
-m配置项告诉 Git,应该采用哪个分支的变动。它的参数parent-number是一个从1开始的整数,代表原始提交的父分支编号。git cherry-pick -m 1 <commitHash>表示,Cherry pick 采用提交commitHash来自编号1的父分支的变动。一般来说,1号父分支是接受变动的分支,2号父分支是作为变动来源的分支。

git cherry-pick to move to another repository

Cherry pick also supports transferring commits from another repository by first adding that repository as a remote repository.

git remote add target git://gitUrl

The above command adds a remote warehouse target.

Then, grab the remote code locally.

git fetch target

The above command grabs the remote code warehouse to the local.

Next, check out the commit you want to move from the remote repository and get its hash.

git log target/master

Finally, use the git cherry-pick command to transfer the commits.

git cherry-pick <commitHash>

git cherry-pick code conflict

If a code conflict occurs during operation, Cherry Pick will stop and let the user decide how to proceed.

(1)--continue

After the user resolves the code conflict, the first step is to re-add the modified file to the temporary storage area (git add .), and the second step is to use the following command to continue the Cherry pick process.

git cherry-pick --continue

(2) --abort
After a code conflict occurs, abandon the merge and return to the state before the operation.

(3)--quit

After a code conflict occurs, exit Cherry pick, but do not return to the state before the operation.

Cherry-pick conflicts with the stash on the reserved site,
as shown in the figure below, which can be resolved by modifying the file and then git add

insert image description here

Modify the conflict file, git add filename, the problem is solved
insert image description here

View remote branches

When you clone from a remote warehouse, Git actually automatically associates the local master branch with the remote master branch, and the default name of the remote warehouse is origin.

To view information about remote libraries, use git remote:

git remote origin

Alternatively, use git remote -v to display more detailed information:

git remote -v origin 
[email protected]:michaelliao/learngit.git (fetch) origin [email protected]:michaelliao/learngit.git (push)

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

push branch

Pushing a branch means pushing all local commits on the branch to the remote library. When pushing, you need to specify the local branch, so that Git will push the branch to the remote branch corresponding to the remote library:

git push origin master

If you want to push other branches, such as dev, change it to:

git push origin dev

However, it is not necessary to push the local branch to the remote, so which branches need to be pushed and which ones do not?

  • The master branch is the main branch, so it must be synchronized with the remote at all times;
  • The dev branch is a development branch, and all members of the team need to work on it, so it also needs to be synchronized with the remote;
  • The bug branch is only used to fix bugs locally, there is no need to push to remote;
  • Whether the feature branch is pushed to the remote depends on whether you cooperate with your small partners to develop it.

In short, in Git, the branch can be completely local, and you can decide whether to push to the remote according to the needs of the branch!

fetch branch

When multiple people collaborate, everyone will push their own modifications to the master and dev branches.
Now, if your friend wants to develop on the dev branch, he must create a remote origin dev branch to the local, so he uses this command to create a local dev branch:

git checkout -b dev origin/dev

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

The push failed because your friend's latest submission conflicts with the submission you are trying to push. The solution is also very simple. Git has already prompted us to use git pull to grab the latest submission from origin/dev first, and then locally Merge, resolve conflicts, and push:

git pull 
There is no tracking information for the current branch. Please specify which branch you want to merge with. See git-pull(1) for details.

git pull <remote> <branch>
If you wish to set tracking information for this branch you can do so with:

git branch --set-upstream-to=origin/<branch> dev

Git pull also failed because the link between the local dev branch and the remote origin/dev branch was not specified. According to the prompt, set the link between dev and origin/dev:

git branch --set-upstream-to=origin/dev dev 
Branch 'dev' set up to track remote branch 'dev' from 'origin'.

Pull again:

git pull 
Auto-merging env.txt CONFLICT (add/add): Merge conflict in env.txt Automatic merge failed; fix conflicts and then commit the result.

This time the git pull is successful, but there is a conflict in the merge, which needs to be resolved manually. The solution is exactly the same as the conflict resolution in branch management. After solving, submit and push again:

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

First, you can try to use git push origin to push your own modifications;
if the push fails, because the remote branch is newer than your local branch, you need to use git pull to try to merge first;
if there is a conflict in the merge, resolve the conflict and submit it locally;
no After conflicts or conflicts are resolved, use git push origin to push successfully!
If git pull prompts no tracking information, it means that the link relationship between the local branch and the remote branch has not been created. Use the command git branch --set-upstream-to origin/.

This is the working mode of multi-person collaboration. Once you are familiar with it, it is very simple.

git rebase

When releasing a version, we usually put a tag (tag) in the repository first, so that the version at the moment of tagging is uniquely determined. Whenever in the future, fetching a tagged version is to fetch the historical version at the moment of tagging. So, a tag is also a snapshot of the repository.

Although the label of Git is a snapshot of the repository, it is actually a pointer to a commit (is it similar to a branch, right? But branches can be moved, but labels cannot be moved), so creating and deleting labels are done instantly.

As we saw in the previous section, when multiple people collaborate on the same branch, conflicts are prone to occur. Even if there is no conflict, the children's shoes that are pushed later have to be pulled first, merged locally, and then the push can succeed.

  • The rebase operation can organize the local non-push fork submission history into a straight line
  • The purpose of rebase is to make it easier for us to view changes in historical commits, because forked commits require three-way comparisons

Guess you like

Origin blog.csdn.net/weixin_45541762/article/details/130663554