1. Introduction to git
1 Introduction
Git is currently the most advanced distributed version control system in the world . It provides free Git storage for open source projects, and countless open source projects have begun to migrate to GitHub, including jQuery, PHP, Ruby, and more.
So what is a version control system?
The version control system can not only automatically record every file change, but also allow others to collaborate on editing, so you don't have to manage a bunch of similar files yourself, and you don't need to transfer files around. If you want to check a certain change, you only need to check it in the software, which can record every file change.
What is distributed?
CVS and SVN are both centralized version control systems, while Git is a distributed version control system. What is the difference between centralized and distributed version control systems?
Centralized version control system, the version library is stored in the central server. When working, you use your own computer, so you must first obtain the latest version from the central server , and then start working . The content is pushed to the central server. The central server is like a library. If you want 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.
The fatal problem of the centralized version control system is that it must be connected to the Internet to work. It is fine on the local area network, the bandwidth is large enough, and the speed is fast enough. However, if the network speed is slow on the Internet, it may take 5 minutes to submit a 10M file. minutes, too slow
And the distributed version control system has no "central server" at all . Everyone's computer has a complete version library , so when working in this way, there is no need to connect to the Internet, because the version library is on your own computer. Since everyone has a complete version library on their computer, how can multiple people collaborate? For example, you changed file A on your computer, and your colleague also changed file A on his computer. At this time, the two of you only need to push your changes to each other, and you can see each other's changes. up. (When actually using a distributed version control system, in fact, it is rare to push the revision of the version library on the computer between two people, because maybe the two of you are not in the same local area network, and the two computers cannot access each other, or your A colleague is sick, and his computer is not turned on at all. Therefore, a distributed version control system usually also has a computer that acts as a "central server", but the role of this server is only to facilitate the "exchange" of everyone's modifications, without which everyone It works the same way, it’s just that it’s inconvenient to exchange and modify.)
Compared with centralized version control systems, distributed version control systems are much more secure because everyone has a complete version library on their computer. It doesn’t matter if one person’s computer is broken, you can just copy one from someone else. That's it. If there is a problem with the central server of a centralized version control system, no one will be able to work.
2. Installation
Git works fine on Linux, Unix, Mac and Windows
(1) Install Git on Linux
$ git
Enter git
to see if Git is installed on the system. If the following command appears, it means it is not installed.
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
1. A newer version of Debian or Ubuntu Linux executes
sudo apt-get install git
2. An older version of Debian or Ubuntu Linux executes
sudo apt-get install git-core
3. Other versions can be installed directly through the source code. First download the source code from the Git official website, then unzip it and enter: ./config
, make
, sudo make install
these commands to install it.
./config
make
sudo make install
(2) Install Git on Mac OS X
One is to install homebrew, and then install Git through homebrew. For details, please refer to the homebrew documentation: Homebrew — The Missing Package Manager for macOS (or Linux) The Missing Package Manager for macOS (or Linux). http://brew.sh/ The second method is simpler and recommended. It is to install Xcode directly from the AppStore . Xcode integrates Git, but it is not installed by default. You need to run Xcode, select the menu "Xcode" -> "Preferences", and find in the pop-up window "Downloads", select "Command Line Tools", click "Install" to complete the installation.
(3) Install Git on Windows
To use Git on Windows, you can directly download the installer from the Git official website , and then install it according to the default options.
After the installation is completed, find "Git" -> "Git Bash" in the start menu. If something similar to a command line window pops up, it means that Git is installed successfully!
After the installation is complete, you still need to set up the final step, enter on the command line:
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"
Because Git is a distributed version control system, each machine must report its name: your name and email address. Pay attention to the parameters git config
of the command --global
. Using this parameter means that all Git warehouses on your machine will use this configuration. Of course, you can also specify a different user name and email address for a certain warehouse.
3. Create a version library
What is a version library? The version library is also called the warehouse. You can simply understand it as a directory. All the files in this directory can be managed by Git. Git can track the modification and deletion of each file, so that the history can be tracked at any time, or in It can be "restored" at some point in the future.
(1) First, choose a suitable place and create an empty directory:
$ mkdir zxcvgit
$ cd zxcvgit
$ pwd
pwd
command is used to display the current directory . Use Windows system, please make sure the directory name (including the parent directory) does not contain Chinese
(2) In the second step, use git init
the command to turn this directory into a warehouse that can be managed by Git:
$ git init
In an instant, Git will build the warehouse, and tell you that it is an empty warehouse (empty Git repository). You will find that there is an additional directory under the current directory .git
. This directory is used by Git to track and manage the version library. Don’t do it manually if you have nothing to do. Modify the files in this directory, otherwise the Git repository will be destroyed if the changes are messed up.
If you don't see .git
the directory, it's because the directory is hidden by default, and ls -ah
you can see it with the command.
4. Add the file to the repository
All version control systems can only track changes to text files, such as TXT files, web pages, all program codes, etc. Git is no exception. The version control system can tell you every change, such as adding the word "Linux" on line 5 and deleting the word "Windows" on line 8. Binary files such as pictures and videos can also be managed by the version control system, but there is no way to track the changes of the files. You can only string together each change of the binary files, that is, only know that the picture has changed from 100KB to 120KB, but in the end What has been changed, the version control system does not know and has no way of knowing .
Unfortunately, Microsoft's Word format is in binary format, so version control systems cannot track changes to Word files. To actually use a version control system, you must write files in plain text . It is strongly recommended to use the standard UTF-8 encoding. All languages use the same encoding, which has no conflicts and is supported by all platforms.
Special attention should be paid to using Windows: never use the Windows built-in Notepad to edit any text files . The reason is that you will encounter many unbelievable problems, for example, a "?" may be displayed on the first line of the web page, and a grammatical error will be reported as soon as the obviously correct program is compiled, etc., all of which are caused by the mentally handicapped behavior of Notepad . It is recommended that you download Visual Studio Code instead of Notepad, which is not only powerful, but also free!
(1) Now we write a readme.txt
file with the following content:
Execute downstream code
$ vi reademe.txt
Enter edit mode: press the i key. Enter the following
Git is a version control system.
Git is free software.
Press Esc to exit editing mode and return to normal mode. Enter : mq to save and exit.
It must be placed zxcvgit
in a directory (subdirectories are also acceptable), because this is a Git repository, and no matter how powerful Git is placed elsewhere, it will not be able to find this file.
(2) It only takes two steps to put a file into the Git warehouse
1. The first step is to tell Git with the command to add the file to the warehouse:git add
$ git add readme.txt
Execute the above command and nothing is displayed, indicating that the addition was successful. The philosophy of Unix is "No news is good news"
Q: Enter
git add readme.txt
, get error:fatal: not a git repository (or any of the parent directories)
.A: Git commands must be executed within the Git repository directory (
git init
with exceptions). It is meaningless to execute them outside the repository directory.
Q: Enter
git add readme.txt
, get errorfatal: pathspec 'readme.txt' did not match any files
.A: When adding a file, the file must exist in the current directory. Use the
ls
ordir
command to check the files in the current directory to see if the file exists or if the file name is written incorrectly.
Q: Enter
git add readme.txt
, get error:fatal: not a git repository (or any of the parent directories)
.A: Git commands must be executed within the Git repository directory (
git init
with exceptions). It is meaningless to execute them outside the repository directory.
Q:输入
git add readme.txt
,得到错误warning: LF will be replaced by CRLF in readme.txt. The file will have its original line endings in your working directoryA: Execute $ git config --global core.autocrlf true (#Convert to LF when submitting, convert to CRLF when checking out)
(2) In the second step, use the command to tell Git to submit the file to the warehouse:git commit
$ git commit -m "wrote a readme file"
git commit
Command, -m
followed by the description of this submission, you can enter any content, of course it is best to be meaningful, so that you can easily find the change record from the history record.
git commit
After the command is successfully executed, it will tell you, 1 file changed
: 1 file has been changed (our newly added readme.txt file); 2 insertions
: Two lines of content have been inserted (readme.txt has two lines of content). I have two files here, so the numbers are different.
commit
It is possible to submit many files at once, so you can submit add
different files multiple times, such as:
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."
To initialize a Git repository, use git init
the command.
Add files to the Git repository in two steps:
- Use the command
git add <file>
. Note that it can be used multiple times to add multiple files; - Use the command
git commit -m <message>
to complete.
2. Version forward and backward
1. Modify files
We have successfully added and submitted a readme.txt file. Now, we continue to modify the readme.txt file to the following content:
Git is a distributed version control system.
Git is free software.
Run git status
the command to see the result. git status
The command allows us to keep track of the current status of the warehouse.
$ git status
The output of the above command tells us that readme.txt
the modification has been modified, but it is not yet ready to be submitted.
Use git diff
this command to check what content has been modified. git diff
As the name suggests, it is to check the difference. The displayed format is the common diff format of Unix. You can see from the output of the following command that we have added a distributed
word in the first line.
$ git diff
Committing revisions and submitting new files is the same two steps, the first step is git add
:
$ git add readme.txt
Again no output. Before executing the second step git commit
, let’s run again git status
to see the status of the current warehouse:
git status
Tell us that the changes to be submitted include readme.txt
, next step, you can submit with confidence:
After submitting, let's use git status
the command to see the current status of the warehouse:
Git tells us that there are currently no changes that need to be committed, and that the working directory is clean (working tree clean).
-
To keep track of the state of the workspace, use
git status
the command. -
If
git status
you are told that a file has been modified, yougit diff
can view the modified content with it.
2. Version rollback
Now, I have learned to modify the file, and then submit the modification to the Git repository. Now, practice again and modify the readme.txt file as follows:
Git is a distributed version control system.
Git is free software distributed under the GPL.
Then try submitting:
$ git add readme.txt
$ git commit -m "append GPL"
Constantly modify the file, and then continuously submit the modification to the version library, just like when playing an RPG game, every time you pass a level, the game state will be automatically saved. If a certain level has not passed, you can also choose to read the previous level status. Sometimes, before fighting the boss, you will manually save the game, so that if you fail to fight the boss, you can restart from the nearest place. Git is the same, whenever you feel that the file has been modified to a certain extent, you can "save a snapshot", this snapshot is called in Git commit
. Once you mess up a file, or delete a file by mistake, you can commit
restore from the most recent one and continue working instead of losing months of work.
Recall that readme.txt
several versions of the file have been submitted to the Git repository:
Version 1: wrote a readme file
Git is a version control system.
Git is free software.
Version 2: add distributed
Git is a distributed version control system.
Git is free software.
Version 3: append GPL
Git is a distributed version control system.
Git is free software distributed under the GPL.
In actual work, it is impossible to remember what has been changed every time in a file with several thousand lines. In Git, we use git log
the command to view the history. git log
The command displays the commit log from the most recent to the farthest. We can see 3 commits, the most recent one append GPL
, the previous one add distributed
, and the earliest one wrote a readme file
.
If you think the output information is too messy, you can try adding --pretty=oneline
parameters:
What I see 52f3ad03...
is a series of similar ones commit id
(version number) . Unlike SVN, Git commit id
is not an increasing number of 1, 2, 3..., but a very large number calculated by SHA1, in hexadecimal. means , and what you see commit id
is definitely different from mine, your own shall prevail. Why commit id
do we need to use such a large series of numbers to represent it? Because Git is a distributed version control system, and multiple people work in the same version library, if everyone uses 1, 2, 3... as version numbers, conflicts will definitely occur. Every time a new version is submitted, Git will actually automatically string them together into a timeline. If you use a visual tool to view Git history, you can see the timeline of commit history more clearly.
How to roll back to the previous version, that is, the version readme.txt
?add distributed
First of all, Git must know which version the current version is . In Git, use HEAD
represents the current version , which is the latest submission (note that my submission ID is definitely different from yours), the previous version is , and the previous version is , Of course, writing 100 versions of the previous 100 versions is easier than counting, so it is written .52f3ad
...
HEAD^
HEAD^^
^
HEAD~100
Now, if we want to append GPL
roll back the current version to the previous version add distributed
, we can use git reset
the command:
$ git reset --hard HEAD^
--hard
What do the parameters mean? I will talk about this later, but you can use it with confidence now.
The cat readme.txt command checks whether readme.txt
the content is the versionadd distributed
:
$ cat readme.txt
It was indeed restored. Let's take git log
another look at the current status of the repository:
The latest version append GPL
is no longer available! If you want to go back, you can't go back, what should you do? In fact, there is still a way. As long as the command line window above has not been closed, you can search up and find the one append GPL
,commit id
52f3ad03...
so you can specify to return to a certain version in the future:
$ git reset --hard 52f3a
There is no need to write down the entire version number, just the first few digits, and Git will find it automatically. Of course, you can't just write the first one or two, because Git may find multiple version numbers and it won't be able to determine which one it is. Things to check out again readme.txt
:
Hahaha, I, Hu Hansan, am back again.
Git's version rollback is very fast because Git has an internal pointer to the current version HEAD
. When you roll back the version, Git just changes HEAD from pointing append GPL
to pointingadd distributed,
and updates the files in the workspace by the way. So whichever version number you HEAD
point to, you will locate the current version.
------->>>
So what should you do if you revert to a certain version, turn off the computer, and want to restore to a new version? What should I do if I can’t find the new version commit id
? When you $ git reset --hard HEAD^
roll back to add distributed
a version and want to restore it again append GPL
, you must find append GPL
the commit id. Git provides a command git reflog
to record each of your commands:
$ git reflog
As you can see from the output, append GPL
the commit id is 52f3ad0
, now, you can go back to the latest version.
-
HEAD
The version pointed to is the current version, Git allows us to shuttle between versions of the history, use the commandgit reset --hard commit_id
-
Before shuttling, users
git log
can view the commit history to determine which version to roll back to. -
To go back to the future,
git reflog
view the command history with to determine which version of the future to go back to.
3. Work area and temporary storage area
One difference between Git and other version control systems such as SVN is the concept of staging area. Working Directory is the directory you can see on your computer. For example, my zxcvgit
folder is a workspace. There is a hidden directory in the workspace .git
. This is not the workspace, but the Git repository. There are many things stored in Git's version library, the most important of which is the temporary storage area called stage (or index) , as well as the first branch automatically created by Git for us master
, and a pointer to itmaster
HEAD
.
As mentioned earlier, when we add files to the Git repository, we do it in two steps :
The first step is to git add
add the file, which actually means adding the file modifications to the temporary storage area;
The second step is to git commit
submit 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
it is to master
commit changes to the branch. A simple understanding is 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.
Real knowledge comes from practice. Now, let's practice again, first make readme.txt
a modification, such as adding a line:
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
然后,在工作区新增一个LICENSE
文本文件(内容随便写)。
先用git status
查看一下状态:
Git非常清楚地告诉我们,readme.txt
被修改了,而LICENSE
还从来没有被添加过,所以它的状态是Untracked
。现在,使用两次命令git add
,把readme.txt
和LICENSE
都添加后,用git status
再查看一下:
现在,暂存区的状态就变成这样了:
所以,git add
命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit
就可以一次性把暂存区的所有修改提交到分支。
一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:
现在版本库变成了这样,暂存区就没有任何内容了:
暂存区是Git非常重要的概念,弄明白了暂存区,就弄明白了Git的很多操作到底干了什么。没弄明白暂存区是怎么回事,请向上滚动页面,再看一次。
4、管理修改
下面,我们要讨论的就是,为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件。什么是修改?比如你新增了一行,这就是一个修改,删除了一行,也是一个修改,更改了某些字符,也是一个修改,删了一些又加了一些,也是一个修改,甚至创建一个新文件,也算一个修改。为什么说Git管理的是修改,而不是文件呢?我们做一个实验。
The first step is to make a modification to readme.txt , for example, add a line with the following content, and then add:
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.
Then, modify readme.txt and submit
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.
Why was the second modification not submitted? Let’s review the operation process:
First modification-> git add
-> Second modification-> git commit
Git manages modifications. When you use git add
the command, the first modification in the workspace is put into the temporary storage area and is ready to be submitted . However, the second modification in the workspace is not put into the temporary storage area , so, git commit
It is only responsible for submitting the modifications to the temporary storage area , that is, the first modification is submitted, and the second modification will not be submitted.
After submission, git diff HEAD -- readme.txt
you can use the command to view the difference between the latest versions in the workspace and the repository :
It can be seen that the second modification has not been submitted. So how to submit the second revision? You can continue git add
,git commit
or you can not rush to submit the first modification, but first git add
modify the second modification, and then git commit
, it is equivalent to merging the two modifications and submitting them together.
First modification-> git add
-> Second modification-> git add
-> git commit
Every time a modification is made, if it does not git add
go to the temporary storage area, it will not be added to it commit
.
5. Undo modifications
没有git add
To the staging area:
Naturally, you can do no wrong. But it's two o'clock in the morning, you're rushing to a work report, and you readme.txt
add a line to
$ vi 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.
My stupid boss still prefers SVN.
Before you are ready to commit, you suddenly realize that since the error was discovered immediately, it can be easily corrected (you can delete the last line and manually restore the file to the previous version). If you use git status
it, check it out:
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
You can find that Git will tell you that git checkout -- file
you can discard the changes in the workspace:
$ git checkout -- readme.txt
The meaning of the command git checkout -- readme.txt
is to readme.txt
undo all modifications to the file in the workspace. There are two situations here: one is that readme.txt
it has not been placed in the temporary storage area since the modification. Now, undoing the modification will return to the same state as the version library ; The first is that readme.txt
after it has been added to the staging area, modifications have been made. Now, undoing the modification will return to the state after adding it to the staging area. In short, it is to return the file to its most recent git commit
state git add
.
Now, take a look readme.txt
at the file contents:
$ 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.
The file contents were indeed restored.
git checkout -- file
The "" in the command --
is very important. If not --
, it becomes a "switch to another branch" command. We will encounter git checkout
the command again in the subsequent branch management.
git add
Reached the staging area:
Now suppose it is 3 in the morning, and you not only wrote some nonsense, but also git add
went to the temporary storage area. Fortunately, commit
you discovered this problem before. Use git status
to check, the modification is only added to the temporary storage area, and has not been submitted yet
In Git, you can use the command git reset HEAD <file>
to unstage the modification in the temporary storage area and put it back into the workspace. git reset
The command can roll back the version or roll back the modification in the temporary storage area to the workspace. When we use HEAD
it, it means the latest version. Check again git status
. Now the temporary storage area is clean and the workspace has been modified:
Remember how to discard workspace changes? The whole world is finally peaceful!
What if you not only corrected something wrong, but also submitted it from the staging area to the repository ? Remember the section on version rollback? You can go back to the previous version. However, this is conditional, that is, you have not pushed your local repository to the remote one . Remember when Git was a distributed version control system? We will talk about the remote repository later. Once you stupid boss
push the submission to the remote repository, you will be really miserable...
Scenario 1: When you change the contents of a file in the workspace and want to directly discard the modifications in the workspace, use the command git checkout -- file
.
Scenario 2: When you not only change the contents of a file in the workspace, but also add it to the temporary storage area, and want to discard the changes, you need to do it in two steps. The first step is to use the command to return to scenario 1. The second step is to press the git reset HEAD <file>
scene 1 operation.
Scenario 3: When inappropriate modifications have been submitted to the repository and you want to undo this submission, refer to the version rollback section, but the premise is that it has not been pushed to the remote repository.
Careful readers will find that the picture git prompt command is different. Below is the new version command.
new version
- Case 1: The file is only operated in the workspace and is not added. Undo operation: git restore <file>. Result: The workspace file is rolled back.
- Case 2: The file has been added but not committed. Undo operation: git restore --staged <file>. Result: The files in the temporary storage area are rolled back, but the files in the workspace are not rolled back. If you need to continue rolling back, follow the situation 1.
- Case 3: The file has been added and committed. Undo operation: git reset --hard commit_id. Result: Workspace files, staging area files, and local warehouse are all rolled back
6. Delete files
In Git, deletion is also a modification operation. Let’s try it in practice. First, add a new file test.txt
to Git and submit it:
Under normal circumstances, you usually delete useless files directly in the file manager, or rm
delete them with the command:
$ rm test.txt
At this time, Git knows that you have deleted the file, so the workspace and the version library are inconsistent, and the git status
command will immediately tell you which files have been deleted:
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
Now you have two options, one is to really delete the file from the repository , then use the command git rm
to delete it, and git commit
:
The file is deleted from the repository.
Another situation is that the deletion is wrong, because there are still files in the version library, so you can easily restore the accidentally deleted files to the latest version
git checkout -- test.txt
git checkout
In fact, it replaces the version in the workspace with the version in the version library. No matter whether the workspace is modified or deleted, it can be "one-click restore".
Command git rm
is used to delete a file. If a file has been submitted to the repository, you never have to worry about accidentally deleting it, but be careful, you can only restore the file to the latest version, and you will lose the content you modified after the most recent submission.
3. Remote warehouse
Git is a distributed version control system. The same Git warehouse can be distributed to different machines. How to distribute it? At first, there must be only one machine with an original version library. After that, other machines can "clone" this original version library, and the version library of each machine is actually the same, and there is no primary or secondary distinction. There is a magical website called GitHub. As you can tell from the name, this website provides Git warehouse hosting services. Therefore, as long as you register a GitHub account, you can get a Git remote warehouse for free . The domestic version uses gitee, and github is the foreign version.
Before continuing to read the following content, please register a Gitee account by yourself. Since the transmission between your local Git repository and the GitHub repository is encrypted via SSH, a little setup is required:
Step 1: Create SSH Key.
First create a local ssh key. This key is used for verification between the local code repository and the remote repository. Enter the command as follows. It is recommended to fill in the email address used for Gitee registration.
$ ssh-keygen -t rsa -C "[email protected]"
Generating public/private rsa key pair... Enter three times to generate ssh key
Enter the command to view the generated ssh key:
$ cat ~/.ssh/id_rsa.pub
Copy this ssh key and add it to Gitee, Gitee -> Personal Information -> SSH Public Key -> Enter the public key name and public key -> Click OK
Why does GitHub/Gitee need SSH Key? Because GitHub/Gitee needs to recognize that the submission you push is indeed pushed by you, not someone else pretending to be it, and Git supports the SSH protocol, so as long as GitHub/Gitee knows your public key, it can confirm that only you can push it. . Of course, GitHub/Gitee allows you to add multiple keys. Suppose you have several computers, and you submit them at the company and at home. As long as you add the key of each computer to GitHub/Gitee, you can push it to GitHub/Gitee on each computer. After ensuring that you have a GitHub/Gitee account, we are about to start learning about remote warehouses.
2. Create a remote library
We need to create a remote code warehouse on Gitee, enter the Gitee web page, log in, click the plus sign to the left of the avatar, and select New Warehouse
Fill in the warehouse information, define the warehouse name yourself, and leave the rest of the options as default. Click OK after completion;
Currently, this warehouse on Gitee zxcvgit
is still empty. Gitee tells us that you can clone a new warehouse from this warehouse, or you can associate an existing local warehouse with it, and then push the contents of the local warehouse to the Gitee warehouse. .
zxcvgit
Now, we follow Gitee's prompts and run the command in the local repository:
$ git remote add origin [email protected]:michaelliao/learngit.git
Note, replace the above michaelliao
with your own Gitee account name . Otherwise, what you associate locally is my remote library. There is no problem with the association, but you will not be able to push it in the future because your SSH Key public key is not with me. in the account list.
After adding, the name of the remote library is origin
. This is the default name of Git. It can also be changed to something else, but origin
this name will tell you that it is a remote library at a glance.
In the next step, you can push all the contents of the local library to the remote library:
$ git push -u origin master
To push the contents of the local library to the remote, use git push
the command to actually push the current branch master
to the remote.
Since the remote library is empty, master
when we push the branch for the first time, we add -u
parameters. Git will not only push the local master
branch content to the remote new branch, but also associate master
the local master
branch with the remote branch. In the future, master
This simplifies commands when pushing or pulling. After the push is successful, you can immediately see on the Gitee page that the content of the remote library is exactly the same as the local one.
From now on, as long as you make a commit locally, you can pass the command:
$ git push origin master
Push the latest modifications of the local master
branch to Gitee
When you use Git clone
or push
the command to connect to GitHub for the first time, you will get a warning:
The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)?
Just enter and press yes
Enter. Git will output a warning telling you that the GitHub Key has been added to a trust list on this machine.
Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
This warning will only appear once, and there will be no warnings for subsequent operations.
Delete remote library
如果添加的时候地址写错了,或者就是想删除远程库,可以用git remote rm <name>
命令。使用前,建议先用git remote -v
查看远程库信息:
$ git remote -v
origin [email protected]:michaelliao/learn-git.git (fetch)
origin [email protected]:michaelliao/learn-git.git (push)
然后,根据名字删除,比如删除origin
:
$ git remote rm origin
此处的“删除”其实是解除了本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何改动。要真正删除远程库,需要登录到Gitee,在后台页面找到删除按钮再删除。
要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git
;
关联一个远程库时必须给远程库指定一个名字,origin
是默认习惯命名;
关联后,使用命令git push -u origin master
第一次推送master分支的所有内容;
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master
推送最新修改;
3、从远程仓库克隆
上次我们讲了先有本地库,后有远程库的时候,如何关联远程库。假设我们从零开发,那么最好的方式是先创建远程库,然后,从远程库克隆。首先,登陆Gitee,创建一个新的仓库,名字叫gitskills
我们勾选Initialize this repository with a README
,这样GitHub会自动为我们创建一个README.md
文件。创建完毕后,可以看到README.md
文件.
现在,远程库已经准备好了,下一步是用命令git clone
克隆一个本地库:
$ git clone [email protected]:michaelliao/gitskills.git
注意把Git库的地址换成你自己的,然后进入gitskills
目录看看,已经有README.md
文件了:
$ cd gitskills
$ ls
README.md
要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone
命令克隆。
Git supports multiple protocols, including Git https
, but ssh
the protocol is the fastest.
4. Branch Management
What is the use of branches in practice? Suppose you are going to develop a new feature, but it takes two weeks to complete. You wrote 50% of the code in the first week. If you submit it immediately, because the code has not been written yet, the incomplete code base will cause others to be unable to work. If you wait until all the code is written before submitting it, there is a huge risk of losing daily progress. Now that you have a branch, you don't have to be afraid. You create a branch that belongs to you, others cannot see it, and continue to work normally on the original branch, while you work on your own branch, submit it if you want, until the development is complete, and then merge it into On the original branch, this is safe and does not affect other people's work. Git's branches are different. Whether you create, switch or delete branches, Git can complete it within 1 second! Whether your repository is 1 file or 10,000 files.
1. Create and merge branches
In version rollback, Git strings each submission into a timeline, and this timeline is a branch . As of now, there is only one timeline. In Git, this branch is called the main branch, that is, the master
branch ( HEAD
strictly speaking, it does not point to the commit, but points master
to master
the commit, so HEAD
it points to the current branch). At the beginning, master
the branch is a line. Git master
points to the latest commit, and then HEAD
points to it master
to determine the current branch and the commit point of the current branch.
With each commit, master
the branch moves forward one step, so that as you keep committing, master
the branch line gets longer and longer.
When we create a new branch, for example dev
, Git creates a new pointer called dev
, pointing to master
the same commit, and then HEAD
points to it dev
, which means that the current branch is dev
on
From now on, modifications and submissions to the workspace are for dev
branches. For example, after a new submission, dev
the pointer moves forward one step, but master
the pointer remains unchanged.
If our dev
work on above is completed, we can dev
merge it into master
above. How to merge Git? The simplest method is to directly commit the master
current dev
point to complete the merge:
After merging branches, you can even delete dev
them. Deleting dev
a branch means dev
deleting the pointer. After deleting it, we are left with one master
branch .
Let’s start the actual combat.
First we create dev
the branch and then switch to dev
the branch
$ git checkout -b dev
git checkout
The command plus -b
parameters means creation and switching, which is equivalent to the following two commands:
$ git branch dev
$ git checkout dev
Then, use git branch
the command to view the current branch:
git branch
The command will list all branches, and the current branch will be marked with a *
number. Then, we can dev
submit normally on the branch, for example, readme.txt
make a modification, add a line, and then submit
Creating a new branch is quick.
Now that dev
the work on the branch is complete, we can switch back to master
the branch
After switching back to master
the branch, I checked a readme.txt
file again, and the content I just added was gone! Because that commit is on dev
the branch, and master
the commit point of the branch at this moment has not changed.
Merge dev
the work results of the branch into master
the branch
$ git merge dev
git merge
The command is used to merge the specified branch into the current branch. After merging, if you check readme.txt
the content again, you can see that dev
it is exactly the same as the latest commit of the branch. Notice the above Fast-forward
information , Git tells us that this merge is in " fast forward mode ", that is, the current commit pointed to is directly master
committeddev
, so the merge speed is very fast. Of course, not every merge is possible Fast-forward
. We will talk about other ways of merging later.
Once the merge is complete, you can safely delete dev
the branch
$ git branch -d dev
After deleting it, check it and you will see branch
that only master
the branch is left.
$ git branch
switch
We noticed that the same command has two functions when switching branches git checkout <branch>
and undoing modifications mentioned earlier , which is indeed a bit confusing. git checkout -- <file>
In fact, switching branches is switch
more scientific. Therefore, the latest versions of Git provide new git switch
commands to switch branches:
To create and switch to a new dev
branch, use:
$ git switch -c dev
To switch directly to an existing master
branch, you can use:
$ git switch master
Use the new git switch
command, which git checkout
is easier to understand.
View branches:git branch
Create a branch:git branch <name>
Switch branches: git checkout <name>
orgit switch <name>
Create + switch branch: git checkout -b <name>
orgit switch -c <name>
Merge a branch into the current branch:git merge <name>
Delete branch:git branch -d <name>
2. Resolve conflicts
Merging branches is often not smooth sailing. Prepare a new feature1
branch and continue our new branch development
$ git switch -c feature1
Modify readme.txt
the last line to:
Creating a new branch is quick AND simple.
Commit on feature1
the branch:
$ git add readme.txt
$ git commit -m "AND simple"
Switch to master
branch:
$ git switch master
Change the last line of the file on master
the branch readme.txt
to
Creating a new branch is quick & simple.
$ git add readme.txt
$ git commit -m "& simple"
Now, each master
branch and branch have new commits, and it becomes like thisfeature1
In this case, Git cannot perform "quick merge" and can only try to merge the respective modifications, but this merge may cause conflicts. Let's try it:
$ git merge feature1
Sure enough, there was a conflict! Git tells us that readme.txt
there is a conflict in the file and we must manually resolve the conflict before submitting it. git status
You can also tell us the conflicting files:
We can directly view the contents of readme.txt
Git uses <<<<<<<
, =======
, >>>>>>>
to mark the contents of different branches. We modify it as follows and save it.
Creating a new branch is quick and simple.
Submit again:
$ git add readme.txt
Now, master
the branches and feature1
branches become as shown below
git log
You can also see the merge status of branches using parameters.
$ git log --graph --pretty=oneline --abbrev-commit
Finally, delete feature1
the branch:
$ git branch -d feature1
The job is done.
When Git cannot merge branches automatically, it must resolve conflicts first. After resolving conflicts, submit again and the merge is complete.
To resolve conflicts, we need to manually edit the files that failed to merge with Git to the content we want, and then submit them.
You can see the branch merge graph with the command.git log --graph
3. Branch management strategy
Usually, when merging branches, Git will use Fast forward
mode if possible, but in this mode, branch information will be lost after deleting the branch. If you want to force the disabled Fast forward
mode, Git will generate a new commit when merging, so that the branch information can be seen from the branch history.
Let's take a look at the parameters --no-ff
of the method , which means it is disabled :git merge,--no-ff
Fast forward
First, still create and switch dev
branches
$ git switch -c dev
Modify the readme.txt file and submit a new commit:
$ git add readme.txt
$ git commit -m "add merge"
Now, we switch back to master
:
$ git switch master
Prepare to merge dev
branches, please pay attention to --no-ff
the parameters, which means disabled. Fast forward,
Because this merge will create a new commit, add -m
parameters and write the commit description.
$ git merge --no-ff -m "merge with no-ff" dev
After merging, we git log
look at the branch history with:
$ git log --graph --pretty=oneline --abbrev-commit
As you can see, without using Fast forward
the pattern, after merge it looks like this
branching strategy
In actual development, we should conduct branch management according to several basic principles: First, master
the branch should be very stable, that is, it is only used to release new versions, and you cannot usually work on it; then where should you work? All work is done dev
on the branch, that is to say, dev
the branch is unstable. At a certain time, such as when version 1.0 is released, dev
the branch will be merged into the branch master
and master
version 1.0 will be released on the branch; each of you and your friends Everyone dev
works on branches. Everyone has his own branch, and he just dev
needs to merge into branches from time to time. So, the teamwork branch looks like this
When merging branches, add --no-ff
parameters to merge in normal mode. The merged history has branches. It can be seen that the merge has been done, but the fast forward
merge cannot be seen that the merge has been done.
4. Bug branch
In software development, bugs need to be fixed. In Git, because branches are so powerful, each bug can be fixed through a new temporary branch. After repair, the branches are merged, and then the temporary branch is deleted. When you are tasked with fixing a bug codenamed 101, naturally you want to create a branch issue-101
to fix it
$ git branch -d issue-101
But wait, dev
the work currently being done on has not been submitted yet
$ git status
On branch dev
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)new file: hello.py
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)modified: readme.txt
It's not that you don't want to submit, but that the work is only halfway through, and you can't submit it yet. It is estimated that it will take 1 day to complete. However, the bug has to be fixed within two hours, so what? Git also provides a stash
function that can "store" the current work site and continue working after restoring the site later
$ git stash
Now, with git status
view workspace, it is clean (unless there are files that are not managed by Git), so you can safely create branches to fix bugs.
First determine which branch to fix the bug on, assuming that it needs to be fixed on the branch, create a temporary branch master
from :master
$ git checkout master
$ git checkout -b issue-101
Now to fix the bug, you need to change "Git is free software ..." to "Git is a free software ..." and submit:
$ git add readme.txt
$ git commit -m "fix bug 101"
[issue-101 4c805e2] fix bug 101
1 file changed, 1 insertion(+), 1 deletion(-)
After the repair is complete, switch to master
the branch, complete the merge, and finally delete issue-101
the branch:
$ git switch master
$ git merge --no-ff -m "merged bug fix 101" issue-101
Bug fix completed! Now, it’s time to get back to dev
the branch and work!
$ git switch dev
$ git status
On branch dev
nothing to commit, working tree clean
The work area is clean, where is the work site saved just now? Check it out with git stash list
the command:
$ git stash list
stash@{0}: WIP on dev: f52c633 add merge
The work site is still there. Git has stored the stash content somewhere, but it needs to be restored. There are two ways:
One is to use git stash apply
recovery, but after recovery, the stash content is not deleted, you need to use git stash drop
it to delete; the other way is to use it git stash pop
, and the stash content is also deleted during recovery.
You can stash multiple times. When restoring, first use git stash list
View, then restore the specified stash, use the command:
$ git stash apply stash@{0}
After fixing the bug on the master branch, we have to think about it. The dev branch was branched from the master branch early, so this bug actually exists on the current dev branch. So how to fix the same bug on the dev branch? You can repeat the operation once and submit. There is a simpler method. To fix the same bug on dev, we only need to 4c805e2 fix bug 101
"copy" the changes made by this submission to the dev branch . Note: We only want to copy 4c805e2 fix bug 101
the changes made by this commit, not merge the entire master branch .
Git provides a special cherry-pick
command that allows us to copy a specific commit to the current branch
$ git cherry-pick 4c805e2
Git automatically made a commit to the dev branch. Note that the commit of this commit is 1d4b803
not different from the master commit 4c805e2
, because the two commits only have the same changes, but they are indeed two different commits. By using it git cherry-pick
, we don’t need to manually repeat the bug fixing process on the dev branch. Since the bug can be fixed on the master branch and the repair process can be "replayed" on the dev branch, is it okay to fix the bug directly on the dev branch and then "replay" it on the master branch? Of course you can, but you still need to git stash
command the save scene to switch from the dev branch to the master branch.
When fixing a bug, we will fix it by creating a new bug branch, then merge it, and finally delete it;
When the work at hand is not completed, first git stash
check the work site, then go to fix the bug, and then git stash pop
return to the work site;
If you want to merge the bugs fixed on the master branch into the current dev branch, you can use git cherry-pick <commit>
the command to "copy" the modifications submitted by the bug to the current branch to avoid duplication of work.
5. Feature branch
In software development, there are always endless new functions to be continuously added. When adding a new feature, you definitely don’t want to mess up the main branch with some experimental code. Therefore, every time you add a new feature, it is best to create a new feature branch, develop on it, and merge it after completion. Finally, Delete the feature branch.
Now, you have finally received a new task: develop a new feature code-named Vulcan
So prepare to develop:
$ git switch -c feature-vulcan
After 5 minutes, the development is completed:
$ git add vulcan.py
$ git status
$ git commit -m "add feature vulcan"
Switch back dev
and prepare to merge:
$ git switch dev
If all goes well, the feature branch and the bug branch are similar, merged, and then deleted. but! At this moment, I received an order from my superiors, due to insufficient funds, the new function must be cancelled! Although it was done for nothing, this branch containing confidential information must still be destroyed on the spot
$ git branch -d feature-vulcan
error: The branch 'feature-vulcan' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature-vulcan'.
Destruction failed. Friendly reminder from Git, feature-vulcan
the branch has not been merged yet. If you delete it, the modifications will be lost. If you want to force the deletion, you need to use uppercase -D
parameters . Now we force the deletion:
$ git branch -D feature-vulcan
Finally deleted successfully!
To develop a new feature, it is best to create a new branch feature;
If you want to discard a branch that has not been merged, you can git branch -D <name>
delete it by force.
6. Multi-person collaboration
When you clone from a remote warehouse, Git actually automatically associates the local master
branch with the remote branch , and the default name of the remote warehouse is .master
origin
To view information about a remote repository, usegit remote
$ git remote
origin
Or, git remote -v
display more detailed information with:
$ git remote -v
origin [email protected]:michaelliao/learngit.git (fetch)
origin [email protected]:michaelliao/learngit.git (push)
The above shows origin
the addresses that can be crawled and pushed. If you don't have push permission, you won't be able to 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, for example 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?
-
master
The branch is the main branch, so it must be synchronized with the remote at all times; -
dev
The 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 it to the remote, unless the boss wants to see how many bugs you fix every week;
-
Whether the feature branch is pushed to the remote depends on whether you cooperate with your partners to develop on it.
fetch branch
When multiple people collaborate, everyone will push their own modifications to the branch master
.dev
Now, simulate one of your little friends, you can clone it on another computer (note that you need to add the SSH Key to GitHub) or another directory on the same computer
$ git clone [email protected]:michaelliao/learngit.git
When your friend clones from the remote repository, by default, your friend can only see the local master
branch. If you don't believe me, you can use git branch
the command to see:
$ git branch
* master
Now, if your buddy wants to dev
develop on the branch, he must create a remote origin
branch dev
to the local , so he uses this $ git checkout -b dev origin/dev command to create a local dev
branch:
$ git checkout -b dev origin/dev
Now, he can dev
continue to make changes on it, and then dev
branch push
to the remote from time to time:
$ git add env.txt
$ git commit -m "add env"
$ git push origin dev
Your friend has already origin/dev
pushed his commit to the branch, and by chance you have also made changes to the same file and tried to push:
$ cat env.txt
env
$ git add env.txt
$ git commit -m "add new env"
[dev 7bd91f1] add new env
1 file changed, 1 insertion(+)
create mode 100644 env.txt
$ git push origin dev
To github.com:michaelliao/learngit.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to '[email protected]:michaelliao/learngit.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
The push failed because your friend's latest commit conflicts with the commit you are trying to push. The solution is also very simple. Git has already prompted us to grab the latest commit first, and then merge locally to resolve the conflict. Push it againgit pull
origin/dev
$ 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
It also failed because the link between the local dev
branch and the remote origin/dev
branch was not specified. According to the prompts, set the link dev
with origin/dev
:
$ git branch --set-upstream-to=origin/dev dev
The following error occurs zsh: no such file or directory: branch
The reason is that "branch" needs to be replaced with the branch name, such as: git branch --set-upstream-to=origin/master master
Pull again:
$ git pull
This time it was successful, but there were conflicts in the merge, which needed to be resolved manually. The solution was exactly the same as conflict resolutiongit pull
in branch management . After solving, submit, and then push:
$ git commit -m "fix env conflict"
$ git push origin dev
Therefore, the working model of multi-person collaboration usually looks like this:
-
First, you can try to
git push origin <branch-name>
push your own modifications; -
If the push fails, it is because the remote branch is newer than your local branch and you need to try to
git pull
merge it first; -
If there are conflicts in the merge, resolve the conflicts and commit them locally;
-
If there is no conflict or the conflict is resolved,
git push origin <branch-name>
push will be successful!
If git pull
prompted 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 <branch-name> origin/<branch-name>
.
This is how multi-person collaboration works. Once you are familiar with it, it is very simple.
-
To view remote library information, use
git remote -v
; -
If the newly created local branch is not pushed to the remote, it will not be visible to others;
-
Push the branch from the local, use
git push origin branch-name
, if the push fails, firstgit pull
grab the remote new submission; -
Create a branch corresponding to the remote branch locally, use
git checkout -b branch-name origin/branch-name
, and the names of the local and remote branches should be the same; -
To establish an association between a local branch and a remote branch, use
git branch --set-upstream branch-name origin/branch-name
; -
Grab the branch from the remote, use
git pull
, if there is a conflict, first handle the conflict.
7、Foxes
Why can't Git's commit history be a clean straight line?
Try entering the command git rebase
:
$ git rebase
The characteristics of the rebase operation: "organize" the commit history of the fork into a straight line, which looks more intuitive. The disadvantage is that the local fork commit has been modified. Finally, the local branch is pushed to the remote through the push operation: the submission history of the remote branch is also a straight line.
-
The rebase operation can organize the local unpush fork commit 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.
Learning link: https://www.liaoxuefeng.com/wiki/896043488029600/900004590234208