Git系列之二数据管理

1.Git数据管理

1.1提交数据

我们可以简单的把工作目录理解成是一个被Git服务程序管理的目录,Git会时刻的追踪目录内文件的改动,另外在安装好了Git服务程序后,默认就会创建好了一个叫做master的分支,我们直接可以提交数据到主线了。

创建本地的工作目录:

[root@test ~]# mkdir linuxprobe
[root@test ~]# cd linuxprobe

将该目录初始化转成Git的工作目录:

[root@test linuxprobe]# git init 
Initialized empty Git repository in /root/linuxprobe/.git/

Git只能追踪类似于txt文件、网页、程序源码等文本文件的内容变化,而不能判断图片、视频、可执行命令等这些二进制文件的内容变化,所以创建一个新文件。

[root@test linuxprobe]# echo "Initialization Git repository" > readme.txt

现在,运行git status命令看看结果:

[root@test linuxprobe]# git status 
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# readme.txt
nothing added to commit but untracked files present (use "git add" to track)

git status命令可以让我们时刻掌握仓库当前的状态,上面的命令告诉我们,readme.txt被修改过了,但还没有准备提交的修改。

使用git diff查看上次修改过的内容:

[root@test linuxprobe]# git diff readme.txt
diff --git a/readme.txt b/readme.txt
index 5a2cd49..5c85266 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,3 +1,4 @@
 Initialization Git repository
 Git is a distributed version control system.
 Git is free software.
+Git is a distributed version control system.

git diff顾名思义就是查看difference,显示的格式正是Unix通用的diff格式,可以从上面的命令输出看到,我们在第一行添加了一个“distributed”单词。

知道了对readme.txt作了什么修改后,再把它提交到仓库就放心多了,提交修改和提交新文件是一样的两步,第一步是git add

[root@test linuxprobe]# git add readme.txt

 

添加到暂存区后再次修改文件的内容:

[root@test linuxprobe]# echo "Something not important" >> readme.txt

将暂存区的文件提交到Git版本仓库,命令格式为“git commit -m “提交说明”:

[root@test linuxprobe]# git commit -m "add the readme file"
[master (root-commit) 96a36d4] add the readme file
 1 file changed, 4 insertions(+)
 create mode 100644 readme.txt

 

使用git ststus查看当前工作目录的状态,提示被修改了

[root@test linuxprobe]# 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")

因为提交操作只是将文件在暂存区中的快照版本提交到Git版本数据库,所以当你将文件添加到暂存区后,如果又对文件做了修改,请一定要再将文件添加到暂存区后提交到Git版本数据库:

第一次修改 -> git add -> 第二次修改 -> git add -> git commit

查看当前文件内容与Git版本数据库中的差别:

[root@test linuxprobe]# git diff readme.txt
diff --git a/readme.txt b/readme.txt
index 5c85266..4c74b3e 100644
--- a/readme.txt
+++ b/readme.txt
@@ -2,3 +2,4 @@ Initialization Git repository
 Git is a distributed version control system.
 Git is free software.
 Git is a distributed version control system.
+Something not important

使用git add把文件提交到Git版本数据库:

[root@test linuxprobe]# git add readme.txt
[root@test linuxprobe]# git commit -m "added a line of words"
[master 855b9cf] added a line of words
 1 file changed, 1 insertion(+)
[root@test linuxprobe]# git status  #再次查看状态
# On branch master
nothing to commit, working directory clean

有些时候工作目录内的文件会比较多,懒的把文件一个个提交到暂存区,可以先设置下要忽略上传的文件(写入到”工作目录/.gitignore“文件中),然后使用”git add .”命令来将当前工作目录内的所有文件都一起添加到暂存区域。

//忽略所有以.a为后缀的文件。
*.a
//但是lib.a这个文件除外,依然会被提交。
!lib.a
//忽略build目录内的所有文件。
build/
//忽略build目录内以txt为后缀的文件。
build/*.txt
//指定忽略名字为git.c的文件。
git.c

先在工作目录中创建一个名字为git.c的文件:

[root@test linuxprobe]# touch git.c

然后创建忽略文件列表:

[root@test linuxprobe]# vim .gitignore
git.c

添加将当前工作目录中的所有文件快照上传到暂存区:

[root@test linuxprobe]# git commit -m "add the .gitignore file"
[master 245e943] add the .gitignore file
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore

经过刚刚的实验,大家一定发现“添加到暂存区”真是个很麻烦的步骤,虽然使用暂存区的方式可以让提交文件更加的准确,但有时却略显繁琐,如果对要提交的文件完全有把握,我们完全可以追加-a参数,这样Git会将以前所有追踪过的文件添加到暂存区后自动的提交,从而跳过了上传暂存区的步骤,再来修改下文件:

[root@test linuxprobe]# echo "Modified again" >> readme.txt

文件被直接提交到Git数据库:

[root@test linuxprobe]# git commit -a -m "Modified again"
[master 2959951] Modified again
 1 file changed, 1 insertion(+)
[root@test linuxprobe]# git status
# On branch master
nothing to commit, working directory clean

比如想把git.c也提交上去,便可以这样强制添加文件:

[root@test linuxprobe]# git add -f git.c

然后重新提交一次(即修改上次的提交操作):

[root@test linuxprobe]# git commit --amend 

add secoend the .gitignore file

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# (use "git reset HEAD^1 <file>..." to unstage)
#
# modified: .gitignore
# new file: git.c
# new file: git3.c
# new file: git4.c
//我们简单浏览下提交描述,然后输入:wq!保存并退出。
[master db2c1ee] add secoend the .gitignore file
 4 files changed, 2 insertions(+)
 create mode 100644 git.c
 create mode 100644 git3.c
 create mode 100644 git4.c

1.2移除数据

有些时候会想把已经添加到暂存区的文件移除,但仍然希望文件在工作目录中不丢失,换句话说,就是把文件从追踪清单中删除。

1.先添加一个新文件,并上传到暂存区:

[root@test linuxprobe]# touch database
[root@test linuxprobe]# git add database

2.查看当前的Git状态:

[root@test linuxprobe]# git status 
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: database
#

3.将该文件从Git暂存区域的追踪列表中移除(并不会删除当前工作目录内的数据文件):

[root@test linuxprobe]# git rm --cached database
rm 'database'
[root@test linuxprobe]# ls
database git.c readme.txt

此时文件已经是未追踪状态了:

[root@test linuxprobe]# git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# database
no changes added to commit (use "git add" and/or "git commit -a")

而如果我们想将文件数据从Git暂存区和工作目录中一起删除,可以这样操作:
再将database文件提交到Git暂存区:

[root@test linuxprobe]# git add .

使用git rm命令可以直接删除暂存区内的追踪信息及工作目录内的数据文件:

但如果在删除之前数据文件已经被放入到暂存区域的话,Git会担心你勿删未提交的文件而提示报错信息,此时可追加强制删除-f参数

[root@test linuxprobe]# git rm -f database
rm 'database'
[root@test linuxprobe]# ls
git.c readme.txt

查看当前Git的当前状态:

[root@test linuxprobe]# git status 
# On branch master
nothing to commit, working directory clean

1.3移动数据

Git不像其他版本控制系统那样跟踪文件的移动操作,如果要修改文件名称,则需要使用git mv命令:

1.使用git mv进行改名:

[root@test linuxprobe]# git mv readme.txt introduction.txt

2.查看当前状态:

[root@test linuxprobe]# git status 
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: readme.txt -> introduction.txt
#

3.提交文件到Git版本仓库:

[root@test linuxprobe]# git commit -m "changed name"
[master 1aa44b7] changed name
 1 files changed, 0 insertions(+), 0 deletions(-)
 rename readme.txt => introduction.txt (100%)

4.第二种修改方法

其实我们还可以这样来修改文件名,首先将工作目录下的数据文件改名:

[root@test linuxprobe]# mv introduction.txt readme.txt

然后删除Git版本仓库内的文件快照:

[root@test linuxprobe]# git rm introduction.txt
rm 'introduction.txt'

最后再将新的文件添加进入:

[root@test linuxprobe]# git add readme.txt 
[root@test linuxprobe]# git commit -m "changed the file name again"
[master 245824d] changed the file name again
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename introduction.txt => readme.txt (100%)

1.4历史数据

在完成上面的实验后,我们已经不知不觉有了很多次的提交操作了,可以用git log命令来查看提交历史记录:

[root@test linuxprobe]# git log 
commit 245824ddf8d70290fa7b7aa604529d58f542036d
Author: xiejc <443060965@qq.com>
Date: Fri Dec 29 01:11:44 2017 +0800

 changed the file name again

commit 1aa44b7e4d3a989891f6de4544fa10b7d6a11196
Author: xiejc <443060965@qq.com>
Date: Fri Dec 29 00:55:23 2017 +0800

 changed name

commit 8ebd54f0b4fbf6edfd083f1f312c29c03e19acc2
Author: xiejc <443060965@qq.com>
Date: Thu Dec 28 23:56:02 2017 +0800

 delete git3-4.c

commit db2c1eed39d984ce8115130edf21967bb9a73f5c
Author: xiejc <443060965@qq.com>
Date: Thu Dec 28 23:13:40 2017 +0800

 add secoend the .gitignore file

commit 29599519f905069f17eaf4e3663c88df3ef5fff4
Author: xiejc <443060965@qq.com>
Date: Thu Dec 28 22:53:45 2017 +0800

 Modified again

像上面直接执行git log命令后会看到所有的更新记录(按时间排序,最近更新的会在上面),历史记录会除了保存文件快照,还会详细的记录着文件SHA-1校验和,作者的姓名,邮箱及更新时间,如果只想看最近几条记录,可以直接这样操作:

[root@test linuxprobe]# git log -2
commit 245824ddf8d70290fa7b7aa604529d58f542036d
Author: xiejc <443060965@qq.com>
Date: Fri Dec 29 01:11:44 2017 +0800

 changed the file name again

commit 1aa44b7e4d3a989891f6de4544fa10b7d6a11196
Author: xiejc <443060965@qq.com>
Date: Fri Dec 29 00:55:23 2017 +0800

 changed name

我们也可以用-p参数来展开显示每次提交的内容差异,例如仅查看最近一次的差异:

[root@test linuxprobe]# git log -p -1
commit 245824ddf8d70290fa7b7aa604529d58f542036d
Author: xiejc <443060965@qq.com>
Date: Fri Dec 29 01:11:44 2017 +0800

 changed the file name again

diff --git a/introduction.txt b/introduction.txt
deleted file mode 100644
index 53eb420..0000000
--- a/introduction.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Initialization Git repository
-Git is a distributed version control system.
-Git is free software.
-Git is a distributed version control system.
-Something not important
-Modified again
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..53eb420
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,6 @@
+Initialization Git repository
+Git is a distributed version control system.
+Git is free software.
+Git is a distributed version control system.
+Something not important
+Modified again

我们还可以使用--stat参数来简要的显示数据增改行数,这样就能够看到提交中修改过的内容、对文件添加或移除的行数,并在最后列出所有增减行的概要信息(仅看最近一次的提交历史):

[root@test linuxprobe]# git log --stat -1
commit 245824ddf8d70290fa7b7aa604529d58f542036d
Author: xiejc <443060965@qq.com>
Date: Fri Dec 29 01:11:44 2017 +0800

 changed the file name again

 introduction.txt | 6 ------
 readme.txt       | 6 ++++++
 2 files changed, 6 insertions(+), 6 deletions(-)

还有一个超级常用的--pretty参数,它可以根据不同的格式为我们展示提交的历史信息,比如每行显示一条提交记录:

[root@test linuxprobe]# git log --pretty=oneline 
245824ddf8d70290fa7b7aa604529d58f542036d changed the file name again
1aa44b7e4d3a989891f6de4544fa10b7d6a11196 changed name
8ebd54f0b4fbf6edfd083f1f312c29c03e19acc2 delete git3-4.c
db2c1eed39d984ce8115130edf21967bb9a73f5c add secoend the .gitignore file
29599519f905069f17eaf4e3663c88df3ef5fff4 Modified again
245e94376c58d4e114f4a1a6623041d99b860464 add the .gitignore file
855b9cf9b4e3cec1059d2b4ecc612607afe54105 added a line of words
96a36d497b01c77371f46fd075cfd775fbfa0796 add the readme file

--pretty=fuller -2以更详细的模式输出最近两次的历史记录:

[root@test linuxprobe]# git log --pretty=fuller -2
commit 245824ddf8d70290fa7b7aa604529d58f542036d
Author: xiejc <443060965@qq.com>
AuthorDate: Fri Dec 29 01:11:44 2017 +0800
Commit: xiejc <443060965@qq.com>
CommitDate: Fri Dec 29 01:11:44 2017 +0800

 changed the file name again

commit 1aa44b7e4d3a989891f6de4544fa10b7d6a11196
Author: xiejc <443060965@qq.com>
AuthorDate: Fri Dec 29 00:55:23 2017 +0800
Commit: xiejc <443060965@qq.com>
CommitDate: Fri Dec 29 00:55:23 2017 +0800

 changed name

还可以使用format参数来指定具体的输出格式,这样非常便于后期编程的提取分析,常用的格式有:

%s 提交说明。
%cd 提交日期。
%an 作者的名字。
%cn 提交者的姓名。
%ce 提交者的电子邮件。
%H 提交对象的完整SHA-1哈希字串。
%h 提交对象的简短SHA-1哈希字串。
%T 树对象的完整SHA-1哈希字串。
%t 树对象的简短SHA-1哈希字串。
%P 父对象的完整SHA-1哈希字串。
%p 父对象的简短SHA-1哈希字串。
%ad 作者的修订时间。

定制详细的日志输出:

[root@test linuxprobe]# git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset %cn"' --abbrev-commit --date=relative
* 245824d - (HEAD, master) changed the file name again (6 hours ago) xiejc"
* 1aa44b7 - changed name (6 hours ago) xiejc"
* 8ebd54f - delete git3-4.c (7 hours ago) xiejc"
* db2c1ee - add secoend the .gitignore file (8 hours ago) xiejc"
* 2959951 - Modified again (8 hours ago) xiejc"
* 245e943 - add the .gitignore file (8 hours ago) xiejc"
* 855b9cf - added a line of words (9 hours ago) xiejc"
* 96a36d4 - add the readme file (12 hours ago) xiejc"

[root@test linuxprobe]# tail -2 .git/config
[alias]
 hlog = git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset %cn"' --abbrev-commit --date=relative

//以后使用git hlog即可实现复杂的命令

1.5还原历史数据

1.修改文件

[root@test linuxprobe]# echo "Git is a version control system" >> readme.txt

2.提交到git版本数据库

[root@test linuxprobe]# git add readme.txt
[root@test linuxprobe]# git commit -m "Introduction software"
[master a1b07f1] Introduction software
 1 file changed, 1 insertion(+)

3.还原某一次提交的文件快照:

[root@test linuxprobe]# git log --pretty=oneline 
a1b07f1cdcee0b8395fc5120ce8658dcd173388a Introduction software
245824ddf8d70290fa7b7aa604529d58f542036d changed the file name again
1aa44b7e4d3a989891f6de4544fa10b7d6a11196 changed name
8ebd54f0b4fbf6edfd083f1f312c29c03e19acc2 delete git3-4.c
db2c1eed39d984ce8115130edf21967bb9a73f5c add secoend the .gitignore file
29599519f905069f17eaf4e3663c88df3ef5fff4 Modified again
245e94376c58d4e114f4a1a6623041d99b860464 add the .gitignore file
855b9cf9b4e3cec1059d2b4ecc612607afe54105 added a line of words
96a36d497b01c77371f46fd075cfd775fbfa0796 add the readme file

首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交a1b.....3388a,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

4.使用git reset命令来还原数据

[root@test linuxprobe]# git reset --hard HEAD^
HEAD is now at 245824d changed the file name again
[root@test linuxprobe]# cat readme.txt 
Initialization Git repository
Git is a distributed version control system.
Git is free software.
Git is a distributed version control system.
Something not important
Modified again

5.上次提交的Introduction software已经看不见了,若还想恢复需要使用命令git reflog

[root@test linuxprobe]# git log --pretty=oneline 
245824ddf8d70290fa7b7aa604529d58f542036d changed the file name again
1aa44b7e4d3a989891f6de4544fa10b7d6a11196 changed name
8ebd54f0b4fbf6edfd083f1f312c29c03e19acc2 delete git3-4.c
db2c1eed39d984ce8115130edf21967bb9a73f5c add secoend the .gitignore file
29599519f905069f17eaf4e3663c88df3ef5fff4 Modified again
245e94376c58d4e114f4a1a6623041d99b860464 add the .gitignore file
855b9cf9b4e3cec1059d2b4ecc612607afe54105 added a line of words
96a36d497b01c77371f46fd075cfd775fbfa0796 add the readme file
#查看回滚之后的ID
[root@test linuxprobe]# git reflog 
245824d HEAD@{0}: reset: moving to HEAD^
a1b07f1 HEAD@{1}: commit: Introduction software
245824d HEAD@{2}: commit: changed the file name again
1aa44b7 HEAD@{3}: commit: changed name
8ebd54f HEAD@{4}: commit: delete git3-4.c
db2c1ee HEAD@{5}: commit (amend): add secoend the .gitignore file
2963332 HEAD@{6}: commit: add secoend the .gitignore file
2959951 HEAD@{7}: commit: Modified again
245e943 HEAD@{8}: commit: add the .gitignore file
855b9cf HEAD@{9}: commit: added a line of words
96a36d4 HEAD@{10}: commit (initial): add the readme file

6.还原文件内容

如是只是想把某个文件内容还原,就不必这么麻烦,直接用git checkout命令就可以的,先随便写入一段话:

[root@test linuxprobe]# cat readme.txt 
Initialization Git repository
Git is a distributed version control system.
Git is free software.
Git is a distributed version control system.
Something not important
Modified again
Some mistakes words

我们突然发现不应该写一句话的,可以手工删除(当内容比较多的时候会很麻烦),还可以将文件内容从暂存区中恢复:

[root@test linuxprobe]# echo "Some mistakes words" >> readme.txt
[root@test linuxprobe]# git checkout -- readme.txt
[root@test linuxprobe]# cat readme.txt 
Initialization Git repository
Git is a distributed version control system.
Git is free software.
Git is a distributed version control system.
Something not important
Modified again

checkou规则是如果暂存区中有该文件,则直接从暂存区恢复,如果暂存区没有该文件,则将还原成最近一次文件提交时的快照。

1.6命令小结

git init         //将该目录初始化转成Git的工作目录
git add [file1] [file2] ...  //添加指定文件至暂存区
git add [dir]    //添加指定目录至暂存区,包括子目录(递归添加)
git commit -m "注释说明"     //将暂存区的文件提交到Git版本仓库
git status       //查看当前工作目录的状态
git diff [file1] [file2] ...  //查看当前文件内容与Git版本数据库中的差别
git commit -a -m "注释说明"    //文件被直接提交到Git数据库
git add -f [file]   //强制添加文件到缓存区
git commit --amend  //重新提交
git rm --cached [file]   //将该文件从Git暂存区域的追踪列表中移除(并不会删除当前工作目录内的数据文件)
git rm -f [file]    //直接删除暂存区内的追踪信息及工作目录内的数据文件
git mv [file-old] [file-new]  //修改文件名,修改后放入暂存区
git log                       //查看提交历史记录
git log -2                    //查看提交历史记录最新两条
git log -p -1                 //-p参数来展开显示每次提交的内容差异,例如仅查看最近一次的差异
git log --stat -2             //简要的显示数据增改行数
git log --pretty=oneline      //根据不同的格式为我们展示提交的历史信息
git log --pretty=fuller -2    //更详细的模式输出最近两次的历史记录
git reset --hard              //还原历史数据
git reflog                    //查看所有的历史记录包括回滚后的历史记录

 

 

0
如无特殊说明,文章均为本站原创,转载请注明出处

该文章由 发布

这货来去如风,什么鬼都没留下!!!
发表我的评论

Hi,请填写昵称和邮箱!

取消评论
代码 贴图 加粗 链接 删除线 签到