我在d盘建了一个文件夹gitTest,然后鼠标右键,Git Bash Here。输入git init,之后就会在这个目录下创建一个隐藏文件夹.git。这样就把这个目录变成Git可以管理的仓库了。
$ git init
Initialized empty Git repository in D:/gitTest/.git/
.git目录就是git版本库(又叫仓库,repository),.git版本库所在的目录为D:/gitTest,它被称为工作区,目前工作区,除了包含一个隐藏的.git版本库目录外空无一物。
执行git status,该命令可以用来显示工作区和暂存区之间的差异,暂存区和版本库之间的差异,以及工作区中没有被跟踪的文件。
$ git status
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
意思就是:在master分支上,还没有任何提交,可以创建或复制文件,并且用git add命令来让git管理这些文件。
然后我在D:/gitTest下添加一个readme.txt,填写内容‘Git is a version control system.’。
然后执行git status
$ git status
On branch master
No commits yet
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仓库的版本管理对象中。这就需要执行git add命令将其加入暂存区(暂存区就是提交之前的一个临时区域,记录文件提交之前的状态,就是一个虚拟的工作区)中。需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
git add命令可以一次添加多个文件。
git add q.txt w.txt
然后执行git add readme.txt
git add readme.txt
之后会在.git中多出一个index文件,这个文件记录了工作区文件的状态(实际上是暂存区的状态)
然后执行git status
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: readme.txt
暂存区的作用:(linux在做提交操作的时候觉得还需要选择要提交的文件,觉得很麻烦)没有暂存区的时候,比如我要实现一个功能涉及到两个文件,在commit的时候需要选中这两个文件然后提交。有了暂存区后,我改了第一个文件,先add到暂存区,然后改了第二个文件,add到了暂存区。最后再一次性的提交。使用暂存区域的方式可以精心准备要提交的细节。
只能commit暂存区中的东西,如果没有add到暂存区,则无法提交。
然后执行git commit -m ‘wrote a readme file’,-m后面输入的是本次提交的说明
$ git commit -m 'wrote a readme file'
[master (root-commit) 618c798] wrote a readme file
1 file changed, 1 insertion(+)
create mode 100644 readme.txt
执行成功后会告诉你,1个文件被改动,插入了1行内容。
现在执行一下git status
$ git status
On branch master
nothing to commit, working tree clean
在git中,添加文件,修改文件,删除文件都被看做是一次更改。
gitTest,它被称为工作区。工作区中有一个隐藏目录.git,是Git的版本库。版本库中有一个index文件为暂存区。初始化仓库的时候Git会自动创建一个master分支,指向master的一个指针叫HEAD。
然后我在readme.txt中添加一句话Git is free software.
再执行git status
$ 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 diff,该命令可以查看工作区,暂存区,版本库之间的区别。
直接执行git diff就是查看工作区和暂存区的差别。
$ git diff
diff --git a/readme.txt b/readme.txt
index 7f63a40..d8036c1 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1 +1,2 @@
Git is a version control system.
+Git is free software.
\ No newline at end of file
“+”号标出的是新添加的行,被删除的行则用“-”号标出。可以看到,这次只添加了一行。
现在执行git add把文件加入暂存区
$ git add readme.txt
如果现在执行git diff,会什么都不显示,因为现在工作区和暂存区都一样。
查看工作区和版本库(也就是最近提交的那次)的差别
执行git diff HEAD命令
$ git diff HEAD
diff --git a/readme.txt b/readme.txt
index 7f63a40..d8036c1 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1 +1,2 @@
Git is a version control system.
+Git is free software.
\ No newline at end of file
不妨养成这样一个好习惯:在执行git commit命令之前先执行git diff HEAD命令,查看本次提交与上次提交之间的差别,等确认完毕后再进行提交。这里的HEAD是指向当前分支中最新一次提交的指针。
刚刚确认了两个提交之间的差别,现在运行git commit命令
$ git commit -m 'add a word'
[master 0158a2b] add a word
1 file changed, 1 insertion(+)
保险起见,我们查看一下提交日志,确认是否提交成功,输入git log
$ git log
commit 0158a2bfd2996cba5538dd861370e17c65ea31bc (HEAD -> master)
Author: eaglezsx <15732621728@163.com>
Date: Sat Aug 26 18:03:30 2017 +0800
add a word
commit c67475822e29a8a905b62660a77ad9270b7de7c2
Author: eaglezsx <15732621728@163.com>
Date: Sat Aug 26 17:43:08 2017 +0800
wrote a reademe file
如果嫌输出的信息太多,可以在后边加上–pretty=oneline
$ git log --pretty=oneline
0158a2bfd2996cba5538dd861370e17c65ea31bc (HEAD -> master) add a word
c67475822e29a8a905b62660a77ad9270b7de7c2 wrote a reademe file
0158a2bfd…e17c65ea31bc ,这一大串字符是提交的版本号,和SVN不一样,Git的不是1,2,3…这样递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示。因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。
现在我们准备退回到上一个版本,也就是“wrote a reademe file”这个版本,怎么做?
首先,Git必须知道当前的版本是哪个版本,在git中,用HEAD表示当前版本,也就是最新的提交,现在最新的提交版本为“add a word”,上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100
。
执行git reset –hard HEAD^
$ git reset --hard HEAD^
HEAD is now at c674758 wrote a reademe file
在执行git log
$ git log
commit c67475822e29a8a905b62660a77ad9270b7de7c2 (HEAD -> master)
Author: eaglezsx <15732621728@163.com>
Date: Sat Aug 26 17:43:08 2017 +0800
wrote a reademe file
如果我再想退回到add a word版本,就必须找到它的id,但现在git log命令只会显示 wrote a reademe file版本的id。git log命令只能查看以当前状态为终点的历史日志。所以要使用git reflog命令,查看当前仓库的操作日志。
可以执行git reflog,它记录了你的每一次命令
$ git reflog
c674758 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
0158a2b HEAD@{1}: commit: add a word
c674758 (HEAD -> master) HEAD@{2}: commit (initial): wrote a reademe file
执行git reset –hard c674758
$ git reset --hard c674758
HEAD is now at c674758 wrote a reademe file
执行git reflog
$ git reflog
c674758 (HEAD -> master) HEAD@{0}: reset: moving to c674758
c674758 (HEAD -> master) HEAD@{1}: reset: moving to HEAD^
0158a2b HEAD@{2}: commit: add a word
c674758 (HEAD -> master) HEAD@{3}: commit (initial): wrote a reademe file
现在readme.txt中的内容为Git is a version control system.我在下边添加一句话My stupid boss still prefers SVN.保存文件,然后执行
$ git diff
diff --git a/readme.txt b/readme.txt
index 7f63a40..458b9bb 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1 +1,2 @@
Git is a version control system.
+My stupid boss still prefers SVN.
这是可以看到工作区相对于暂存区多写了一句话。如果我想撤销工作区的这个修改可以执行git checkout – readme.txt
$ git checkout -- readme.txt
执行完后我在工作区添加的那一句话就被撤销了。现在再执行git diff,啥都不会显示。
现在我还加上那一句话,并且git add到暂存区。如果想把暂存区的修改撤销掉,可以执行git reset HEAD readme.txt
$ git reset HEAD readme.txt
Unstaged changes after reset:
M readme.txt
然后执行git status
$ 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")
可以看到Changes not staged for commit
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout – 文件名称。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。
删除文件操作。git管理的是修改,删除文件也算是一个修改。比如我新建了个c.txt,然后我git add c.txt,然后git commit -m ‘add c.txt’。现在我在工作区中把c.txt删除。然后git add c.txt,然后git commit -m ‘remove c.txt’。
现在,在工作区中删除c.txt和执行git add c.txt这两个操作可以合并为一个操作,就是执行git rm c.txt。