Git,世界上目前最先进的分布式版本控制系统。
在Git诞生以前,也存在一些版本控制的系统,例如CVS和SVN等。CVS和SVN是集中式版本控制系统。用户在使用集中是版本控制系统,在进行撸代码前需要通过网络把代码从服务器中下载下来,撸完代码需要再将代码上传到服务器,在那个上网需要使用电话线的年代,网速太慢,导致使用集中式版本控制系统十分的令人苦恼。
Git的安装(Linux)
在Linux中安装Git,以Ubuntu为例,使用sudo apt-get install git
进行Git的安装。也可以通过源码进行安装,不再叙述。
进行相应的设置
leeguo@leeguo-PC:~/Nutstore/Code$ git config --global user.name "*****"
leeguo@leeguo-PC:~/Nutstore/Code$ git config --global user.email "****@*****.com"
创建版本库(repository)
版本库,也可以理解为一个仓库,用于存放代码,也就是一个目录。这个目录里的所有的文件都被Git管理起来。Git跟踪每一个文件改动。
创建一个版本库很简单,创建一个哭的目录,就可以作为一个版本库。
leeguo@leeguo-PC:~/Nutstore$ mkdir Code
leeguo@leeguo-PC:~/Nutstore$ cd Code/
leeguo@leeguo-PC:~/Nutstore/Code$ pwd
/home/leeguo/Nutstore/Code
通过git init
将当前的目录变为版本库。
leeguo@leeguo-PC:~/Nutstore/Code$ git init
Initialized empty Git repository in /home/leeguo/Nutstore/Code/.git/
版本库创建完成,在创建版本库的同时,也自动创建了一个.git
的文件夹,文件夹中有各种文件,用于管理版本库的。
leeguo@leeguo-PC:~/Nutstore/Code$ cd .git/
leeguo@leeguo-PC:~/Nutstore/Code/.git$ ls
branches config description HEAD hooks info objects refs
把文件添加到版本库
在版本库的文件夹/子文件夹中创建一个文件,例如readme.txt
文件,写入一些内容。
使用git add
把文件添加到版本库。
leeguo@leeguo-PC:~/Nutstore/Code$ git add readme.txt
使用git commit
说明本次提交的说明,以便后期便于查找。
leeguo@leeguo-PC:~/Nutstore/Code$ git commit -m "wrote a readme file"[master (root-commit) 3cae6f8] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
查看当前版本库的状态git status
git status
命令可以查看当前版本库的状态。
leeguo@leeguo-PC:~/Nutstore/Code$ git status
On branch master
nothing to commit, working directory clean
文件未做任何的改动,显示这样的信息。
若将readme.txt进行一定的改动。
leeguo@leeguo-PC:~/Nutstore/Code$ 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")
leeguo@leeguo-PC:~/Nutstore/Code$
未进行添加,则显示这样的信息。
查看修改的内容git diff
leeguo@leeguo-PC:~/Nutstore/Code$ git diff readme.txt
diff --git a/readme.txt b/readme.txt
index 0febfab..604f0c2 100644
--- a/readme.txt
+++ b/readme.txt
*************
*************
查看最近提交的文档git log
leeguo@leeguo-PC:~/Nutstore/Code$ git log
commit e3c4b8592f74eba4f939d08c317ffc7f929a0775
Author: leeguo <leeguo@outlook.com>
Date: Fri Oct 20 20:22:52 2017 +0800
add distributed
commit 3cae6f81c2150427258621c7a6b7e542ae8792fb
Author: leeguo <leeguo@outlook.com>
Date: Fri Oct 20 19:50:04 2017 +0800
wrote a readme file
可以看出,是按时间倒序的方式排列。
显示的信息太多,可以使用git log --pretty=oneline
显示部分有用的信息。
leeguo@leeguo-PC:~/Nutstore/Code$ git log --pretty=oneline
e3c4b8592f74eba4f939d08c317ffc7f929a0775 add distributed
3cae6f81c2150427258621c7a6b7e542ae8792fb wrote a readme file
返回到以前的版本git reset --hard ****
在Git中,HEAD
代表当前的版本, HEAD^
代表上一个版本,HEAD^^
代表上上个版本,依次类推。往上50个版本,可以使用HEAD~50
表示。
使用git reset --hard HEAD^
就回到的上一个版本。
后悔了,怎么办?
现在如果后悔了,想回到原来的版本,可以使用git reflog
查看历次版本的信息。
leeguo@leeguo-PC:~/Nutstore/Code$ git reflog
3cae6f8 HEAD@{0}: reset: moving to HEAD^
e3c4b85 HEAD@{1}: commit: add distributed
3cae6f8 HEAD@{2}: commit (initial): wrote a readme file
使用git reset --hard e3c4b85
回到原来版本。
leeguo@leeguo-PC:~/Nutstore/Code$ git reset --hard e3c4b85
HEAD is now at e3c4b85 add distributed
这样就可以在历次的版本中任意的穿梭了。
关于Git的基本知识
工作区
就是你存放代码的目录,例如下上面的例子中,文件夹Code就是工作区。
版本库(Repository)
在工作区中有一个隐藏的文件夹,在上面也已经指出,那就是
.git/
,也就是Git的版本库。
版本库中存放的东西有很多,其中最重要的一个就是
leeguo@leeguo-PC:~/Nutstore/Code/.git$ ll
total 56
drwxrwxr-x 8 leeguo leeguo 4096 10月 20 21:12 ./
drwxrwxr-x 3 leeguo leeguo 4096 10月 20 21:09 ../
drwxrwxr-x 2 leeguo leeguo 4096 10月 20 19:21 branches/
-rw-rw-r-- 1 leeguo leeguo 11 10月 20 21:07 COMMIT_EDITMSG
-rw-rw-r-- 1 leeguo leeguo 92 10月 20 19:21 config
-rw-rw-r-- 1 leeguo leeguo 73 10月 20 19:21 description
-rw-rw-r-- 1 leeguo leeguo 23 10月 20 19:21 HEAD
drwxrwxr-x 2 leeguo leeguo 4096 10月 20 19:21 hooks/
-rw-rw-r-- 1 leeguo leeguo 145 10月 20 21:12 index
drwxrwxr-x 2 leeguo leeguo 4096 10月 20 19:21 info/
drwxrwxr-x 3 leeguo leeguo 4096 10月 20 19:50 logs/
drwxrwxr-x 13 leeguo leeguo 4096 10月 20 21:07 objects/
-rw-rw-r-- 1 leeguo leeguo 41 10月 20 21:09 ORIG_HEAD
drwxrwxr-x 4 leeguo leeguo 4096 10月 20 19:21 refs/
leeguo@leeguo-PC:~/Nutstore/Code/.git$ tree
.
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ └── master
├── objects
│ ├── 04
│ │ └── fae0c4174bd54568e600ace48117a6f5f4290a
│ ├── 0c
│ │ └── f6e883dffd849b279db5fbf3f369a6e9cd0b64
│ ├── 0f
│ │ └── ebfabe9109b4d4acfca0645bbf7ee51108bd58
│ ├── 3c
│ │ └── ae6f81c2150427258621c7a6b7e542ae8792fb
│ ├── 60
│ │ └── 4f0c2acdb3102c6f1693186a9d9bde76975b47
│ ├── 70
│ │ └── 0118e8451fe195febd5608e337229f9b9d962a
│ ├── e3
│ │ └── c4b8592f74eba4f939d08c317ffc7f929a0775
│ ├── f3
│ │ └── f70e2806734078352ec8bf6e983475f8636a5e
│ ├── fb
│ │ └── 2b5b9b21e46db740aa80db418762e6711aa03d
│ ├── info
│ └── pack
├── ORIG_HEAD
└── refs
├── heads
│ └── master
└── tags
在上面已经指出,把文件添加到Git版本库中需要两个步骤:
git add
把文件添加进去,实际上就是把文件添加到的暂存区;git commit
提交更改,实际上就是把暂存区的所有的内容提交到当前的分支中。
可以这样简单的理解。
在创建的Git版本库的时候,Git也就自动创建了一个master
的分支,git commit
也就是再往master
分支中提交更改。
下面做一些简单的测试,开始吧。
先把readme.txt
文件进行修改,并添加一个文件file.txt
。
现在使用git status
进行查看。
leeguo@leeguo-PC:~/Nutstore/Code$ 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
Untracked files:
(use "git add <file>..." to include in what will be committed)
file.txt
no changes added to commit (use "git add" and/or "git commit -a")
现在提示readme.txt
被修改,file.txt
还没有被添加进去。接下来使用git add
,把readme.txt
和file.txt
添加进去。
leeguo@leeguo-PC:~/Nutstore/Code$ git add readme.txt file.txt
leeguo@leeguo-PC:~/Nutstore/Code$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: file.txt
modified: readme.txt
现在的状态就是把文件存放在的暂存区,然后使用git commit
提交到分支。
leeguo@leeguo-PC:~/Nutstore/Code$ git commit -m "add a line twice and create a file"
[master 3bb6dbc] add a line twice and create a file
2 files changed, 1 insertion(+)
create mode 100644 file.txt
现在的暂存区,可以使用git status
查看,发现是空的。
leeguo@leeguo-PC:~/Nutstore/Code$ git status
On branch master
nothing to commit, working directory clean
leeguo@leeguo-PC:~/Nutstore/Code$
综合上面的小实验,可以理解暂存区的存在,下面就可以知道它存在的意义。
管理修改
Git跟踪并管理的是修改,而不是文件本身。这也是它与其他的工具的不同之处,它的优秀之处。
文件修改后必须先git add
把文件添加到暂存区,这样继续使用git commit
把暂存区的文件提交到分支中去。
也就是说(这样翻来覆去的说有点像废话,在这里是为了强调),文件没有git add
把文件放在暂存区,就没有办法把文件添加到的分支里去,这是的固定的步骤。
撤销修改
现在整理工作区撸代码,突然之间发现一个重大的错误。
leeguo@leeguo-PC:~/Nutstore/Code$ cat readme.txt
Git is a distribution version control system.
Git is free sofeware.
Git is useful.
Git is best tool.
I dont know what to say.
Say something what I want to say.
Something wrong. #big trouble
可以手动把错误的地方删除,也可以使用git把文件恢复到这次修改前的状态。
使用git status
可以知道这次的修改并没有刚在暂存区,可以使用git checkout -- file
丢弃这次的修改(注意--
两端是有空格的!!!)
leeguo@leeguo-PC:~/Nutstore/Code$ 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")
leeguo@leeguo-PC:~/Nutstore/Code$ git checkout -- readme.txt
leeguo@leeguo-PC:~/Nutstore/Code$ cat readme.txt
Git is a distribution version control system.
Git is free sofeware.
Git is useful.
Git is best tool.
I dont know what to say.
Say something.
git checkout -- file
命令中的--
很重要,没有--
,就变成了“切换到另一个分支”的命令。
命令git checkout -- readme.txt
意思就是,把readme.txt
文件在工作区的修改全部撤销,这里有两种情况:
-
一种是
readme.txt
自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态; -
一种是
readme.txt
已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit
或git add
时的状态。
可能会遇到另外的一个情况:那就是在把文件使用git add
把文件添加到了暂存区,还没有使用git commit
把文件提交到分支,现在发现文件出现了一个致命的错误。
leeguo@leeguo-PC:~/Nutstore/Code$ cat readme.txt
Git is a distribution version control system.
Git is free sofeware.
Git is useful.
Git is best tool.
I dont know what to say.
Say something what I want to say.
Something wrong. #big trouble
leeguo@leeguo-PC:~/Nutstore/Code$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: readme.txt
用命令git reset HEAD file
可以把暂存区的修改撤销掉(unstage),重新放回工作区。
leeguo@leeguo-PC:~/Nutstore/Code$ git reset HEAD readme.txt
Unstaged changes after reset:
M readme.txt
此时把文件从新放到了暂存区,但是文件认识错误的。
leeguo@leeguo-PC:~/Nutstore/Code$ cat readme.txt
Git is a distribution version control system.
Git is free sofeware.
Git is useful.
Git is best tool.
I dont know what to say.
Say something.
Something wrong.
leeguo@leeguo-PC:~/Nutstore/Code$ 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")
leeguo@leeguo-PC:~/Nutstore/Code$
使用上面的方法git checkout -- readme.txt
把文件恢复到原来的样子。
删除文件
现在在版本库中有两个文件,要求把版本库中的file.txt
删除。
leeguo@leeguo-PC:~/Nutstore/Code$ ls
file.txt readme.txt
若使用rm file.txt
命令只是把文件在工作去把文件进行了删除,而在分支上仍然存在。
leeguo@leeguo-PC:~/Nutstore/Code$ rm file.txt
leeguo@leeguo-PC:~/Nutstore/Code$ 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: file.txt
no changes added to commit (use "git add" and/or "git commit -a")
若想把版本库中的file.txt
也一并删除,可以使用
leeguo@leeguo-PC:~/Nutstore/Code$ git rm file.txt
rm 'file.txt'
leeguo@leeguo-PC:~/Nutstore/Code$ git commit -m "remove file.txt"
[master 926164d] remove file.txt
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 file.txt
leeguo@leeguo-PC:~/Nutstore/Code$
这样就把file.txt
从版本库中删除了。
现在如果在rm file.txt
命令是手误输入错误了,这个时候在版本库中仍存在file.txt
文件,可以使用git checkout -- file.txt
把file.txt
文件回复回来。
生成patch
git format-patch HEAD^
本文参考:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000