感谢廖雪峰大佬的教程,正因为廖雪峰大佬的网站,我才能够git入门
为什么使用git
git是一种开源的分布式版本控制系统,至于版本控制,就是指,如果你想要修改某一个文档,但是又害怕将来存在恢复的可能性,对于此,我们常规的做法就是将文件另存为另外一个文件,之后在接着改。
但是在将来随着修改的次数逐渐增多,另存的文件也会越来越多,导致查找的困难
而git版本控制会自动帮助我们记录每次文件的改动。
安装git
在ubuntu linux系统下可以直接使用apt命令安装
sudo apt install git
设置
$: git config --global user.name "Your Name"
$: git config --global user.email "email@example.com"
git是分布式版本控制系统,所以,每个系统都必须自报家门,也就是名字和邮箱地址,其中--global
是指机器上所有git
仓库都会使用这个配置。
创建版本库
创建目录
使用git首先就需要有一个版本库,版本库中每一个文件都被git管理起来,每个文件的修改和删除都被git监控着,以便于将来的恢复 在操作系统上,他可以被简单理解为目录
$: mkdir learngit
$: cd learngit
$: pwd
/home/user/Data/learngit
也就是说在我的电脑上,版本库位于/home/user/Data/learngit
初始化
-
git init
初始化git仓库
我们创建了目录之后,并不意味着我们就可以进行版本控制了,还需要进行git初始化
$: git init
已初始化空的 Git 仓库于 /home/user/Data/learngit/.git/
$: ls -ah
. .. .git
这样我们就创建了一个空的git仓库,并且可以发现当前目录下多了一个.git文件
将文件添加到版本库
将文件添加到版本库只需要两个步骤,当然首先我们需要有一个文件
我们首先创建一个hellogit.txt的文件,并在其中写入hello git
注意: 这个文件一定要在你所创建的那个版本库的目录,对于我,也就是我所创建的/home/user/Data/learngit
将文件添加到仓库
-
git add <filename>
``添加文件到版本库
其中
git add
可以同时添加多个文件,比如
git add file1 file2
添加file1和file2或者添加当前目录下的所有文件
git add .
git add hellogit.txt
这条命令是没有任何显示的。
将文件提交的仓库
-
git commit -m "***"
提交文件到版本库
git commit
所提交的内容是你使用git add
添加的内容,所以每次添加后,只需要只用一次commit
命令注意: 提交注释尽量写的有意义(请务必写的有意义)
使用git commit
告诉git,将文件提交到仓库
$: git commit -m "first"
[master (根提交) 9b75557] update
1 file changed, 1 insertion(+)
create mode 100644 hellogit.txt
注意: -m 后面输入的是本次提交的说明,最好是有意义的,这样就可以从历史记录中找到改动记录
查看状态
查看当前状态
我们需要使用git status
来检查当前版本库的状态
比如,现在没有进行任何修改,使用git status
来查看状态
$: git status
位于分支 master
无文件要提交,干净的工作区
但是一旦我们修改了hellogit.txt,比如我第一行添加了”wang”这个字符串,又增加了第二行
1 wang hello git
2 hello world
再次使用git status
来查看状态
$: git status
位于分支 master
尚未暂存以备提交的变更:
(使用 "git add <文件>..." 更新要提交的内容)
(使用 "git checkout -- <文件>..." 丢弃工作区的改动)
修改: hellogit.txt
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
查看不同
-
git diff <filename>
查看修改的不同之处
当hellogit.txt被修改时,但是如果我们的git仓库是多人合作的,这就可能是他人进行的修改,而你本人却不清楚发生了什么
这时你就可以使用git diff
命令来查看修改了什么
$: git diff hellogit.txt
diff --git a/hellogit.txt b/hellogit.txt
index 8d0e412..5d66b59 100644
--- a/hellogit.txt
+++ b/hellogit.txt
@@ -1 +1,2 @@
-hello git
+wang hello git
+hello world
可以看出来我们在第一行添加了wang这个字符串,第二行增加了hello world
提交
我们已经得知仓库里有文件被修改,则我们继续使用两部走来提交修改
添加到仓库
首先使用git add hellogit.txt
添加到仓库
使用git status
查看状态
$: git add hellogit.txt
$: git status
位于分支 master
要提交的变更:
(使用 "git reset HEAD <文件>..." 以取消暂存)
修改: hellogit.txt
可以与未使用git add
命令时所使用git status
得到的状态比较,可以看出,这时变成了要提交的变更
提交到仓库
之后使用git commit
命令就可以了,然后可以继续使用git status
来查看状态
$: git commit -m "second"
[master c23c8ec] update
1 file changed, 2 insertions(+), 1 deletion(-)
$ git status
位于分支 master
无文件要提交,干净的工作区
版本回退
git最重要的就是版本回退嘛,现在我们再次修改一次hellogit.txt并将其提交至git仓库
也就是说我们现在有三个版本,对于三个版本,其文件中的内容是不一样的
第一个版本:
hello git
第二个版本:
wang hello git
hello world
第三个版本:
wang hello git
hello world
hello git
查看版本
-
git log
查看提交记录
参数
我们可以使用```--pretty=oneline```来使每次修改显示为一行 第二个参数`--graph`可以用来查看合并分支图 第三个参数`-- abbrev-commit`用来缩略`commit-id`
使用人脑是难以记录下每一个版本的,所以我们可以使用git log
来查看自己的版本信息
$: git log
commit c23c8ec3a7dd672bb80ba5d52b48021e70af05e7 (HEAD -> master)
Author: smithgua <@qq.com>
Date: Sat Jun 29 15:16:48 2019 +0800
update
commit 9b755572332ae4c9569df7a9f8853732a03d4180
Author: smithgua <@qq.com>
Date: Sat Jun 29 14:52:49 2019 +0800
update
emmm你看,就像我,就只是在每次提交时只是使用了git commit -m "update"
所以现在根本看不懂。。。我的每次提交做了什么
重新弄一次
$: git log
Author: smithgua <×××××××××@qq.com>
Date: Sat Jun 29 15:32:33 2019 +0800
third
commit eb48159e62225a7bf8fcc3491cf696aa358e1aef
Author: smithgua <××××××××@qq.com>
Date: Sat Jun 29 15:32:10 2019 +0800
second
commit df117e43e87ed7ffb8a3e32ec7c1554c41ff8d31
Author: smithgua <×××××××@qq.com>
Date: Sat Jun 29 15:31:13 2019 +0800
first
可以看出来自己进行了三次修改,并且最新一次提交是在最上面的
如果你认为输出信息过多,你可以提哪家–pretty=oneine参数
$: git log --pretty=oneline
3aaf2b255f0dcb232878f73ddc7781c20f89a666 (HEAD -> master) third
eb48159e62225a7bf8fcc3491cf696aa358e1aef second
df117e43e87ed7ffb8a3e32ec7c1554c41ff8d31 first
需要注意的是,像3aa.....
这样的是commit id
,也就是你所提交的版本号
git log后面可带的参数有很多,但是最长使用的是git log --graph --pretty=oneline --abbrev-commit
,使用这个命令可以以图形化的样子来查看分支合并
$: git log --graph --pretty=oneline --abbrev-commit
* a0758fa (HEAD -> master) merge with --no-f two
|\
| * 14ade7e (dev) ninth
* | 2e2604d merge with --no-f
|\ \
| |/
| * 5f2e123 eighth
|/
* 02c590f conflict fixed
|\
| * 4d5aa1d fifth
* | 2e910ea sixth
|/
* 021ef09 forth
* f83dd14 third
* 06283ca second
* 805e981 first
版本回退
-
git reset --hard commit_id
版本回溯,其中–hard代表彻底的回溯
需要注意的是,我们既可以使用commit_id也可以使用HEAD来表示回退几个版本
我们需要明白,在git中,我们使用
- HEAD 表示当前版本,
- HEAD^ 表示上一个版本,
- HEAD^^ 表示上上一个版本,
- 对于往上100个版本,则可以使用HEAD~100
现在我们尝试将版本回退到second这个
$: git reset --hard HEAD^
HEAD 现在位于 eb48159 second
然后我们可以查看一下当前文件中的内容, 果然是这样的
$: cat hellogit.txt
wang hello git
hello world
撤回版本回退
-
git reflog
查看命令历史
在我们使用回溯之后,如果我们想要再次回到未来,那么我们只能得到回溯前的commit_id 但是
git log
已经不存在未来的那个commit_id了,所以使用git reflog
来查找commit_id
回退之后,我们查看一下git log
$: git log
Author: smithgua <@qq.com>
Date: Sat Jun 29 15:32:10 2019 +0800
second
commit df117e43e87ed7ffb8a3e32ec7c1554c41ff8d31
Author: smithgua <@qq.com>
Date: Sat Jun 29 15:31:13 2019 +0800
first
我们会发现,第三个版本没了,如果我们想要再次回到第三个版本,我们可以使用git reflog
git reflog
用来记录自己的每一次的命令
$: git reflog
eb48159 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
3aaf2b2 HEAD@{1}: commit: third
eb48159 (HEAD -> master) HEAD@{2}: commit: second
df117e4 HEAD@{3}: commit: first
从上面可以看到第三个版本的commit id是3aaf2b2
现在可以使用git reset
来恢复版本了
$: git reset --hard 3aaf2b2
HEAD 现在位于 3aaf2b2 third
$: cat hellogit.txt
wang hello git
hello world
hello git
远程仓库版本回退
-
git push -f
强制推送
有些时候,当我们将仓库推送到远程仓库之后,却在本地进行了版本回退,之后,我们还需要将远程仓库版本回退,
这个时候,有一种方法就是直接进行强制推送。即在git push
后面添加上-f
。
暂存区
对于暂存区的概念我觉得使用图片来理解更好一些,但是我本人是不会制作图片解释的
所以我推荐你直接看廖雪峰的博客
git之所以使用两个步骤,第一个步骤就是为了将你所修改的内容提交至暂存区,之后使用git commit
就使暂存区中的内容推送到你所在的那条分支中
git还有一个叫做工作区的东西,也就是你所创建的目录。
在我们创建git版本库时,git会自动帮助我们创建唯一的一个master分支,也就是说,git commit
是往master分支提交的
撤销修改
对于撤销修改我们有三种可能,第一种是你只是在工作区修改了文件,但是还没有git add
到暂存区,第二种是你已经git add
到了暂存区,第三种是你已经使用git commit
提交了
对于第一第二种情况,实际上就是将文件回退到最近一次使用git commit
的状态,所以是可以使用git reset
命令进行版本回退,但是还有其他的方法
仅在工作区修改了文件,但是还没有使用git add添加
-
git checkout -- <filename>
清空工作区中的修改
现在我们的hellogit.txt文件中是这样的
$: cat hellogit.txt
wang hello git
hello world
hello git
现在我们删除了第三行hello git
$: cat hellogit.txt
wang hello git
hello world
如果我们想要恢复第三行呢,使用git status
检查一下当前的状态
$: git status
位于分支 master
尚未暂存以备提交的变更:
(使用 "git add <文件>..." 更新要提交的内容)
(使用 "git checkout -- <文件>..." 丢弃工作区的改动)
修改: hellogit.txt
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
我们发现我们并没有将修改提交到暂存区,如果要回复第三行,我们除了使用版本回退之外,还可以直接使用git checkout -- hellogit.txt
丢弃工作区的改动
$: git checkout -- hellogit.txt
$: cat hellogit.txt
wang hello git
hello world
hello git
$: git status
位于分支 master
无文件要提交,干净的工作区
可以看出果然恢复了,并且工作区被清空了
需要注意的是: git checkout
中--
的作用很重要,没有--
就变成了切换到另外的分支
已经使用git add提交至暂存区
-
git reset HEAD <filename>
将暂存区中的内容回退到工作区
在我们不小心提交错误的信息到暂存区中,我们可以使用该命令进行撤回
如果我们已经将修改git add
提交至暂存区了呢
$: cat hellogit.txt
wang hello git
hello world
$: git status
位于分支 master
要提交的变更:
(使用 "git reset HEAD <文件>..." 以取消暂存)
修改: hellogit.txt
系统同样告诉我们,可以使用git reset HEAD <filename>
将暂存区中的内存退回工作区
$: git reset HEAD hellogit.txt
重置后取消暂存的变更:
M hellogit.txt
也就是说git reset
不仅可以回退版本,还可以将暂存区中的修改回退到工作区。使用HEAD
意味着最新的版本
使用git status
检查一下
$: git status
位于分支 master
尚未暂存以备提交的变更:
(使用 "git add <文件>..." 更新要提交的内容)
(使用 "git checkout -- <文件>..." 丢弃工作区的改动)
修改: hellogit.txt
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
可以看出此时暂存区是干净的,而工作去有修改,之后就是第一种情况,使用git checkout -- <filename>
进行撤回就好了
已经使用git commit提交至分支
这种情况可以直接使用版本回退,前提是你没有推送到远程库。
删除文件
在git中删除文件也是一种修改操作,我们首先添加了一个新文件test.txt
$: ls
hellogit.txt test.txt
这种情况也是分为几种的,
情况1:我们直接在工作区创建了文件,但是没有提交,
情况2:我们创建了文件并且提交到了暂存区
情况3:在暂存区中提交了
只是在工作区创建了文件,但是还没有添加到暂存区
首先使用git status
检查一下当前的状态
$: git status
位于分支 master
未跟踪的文件:
(使用 "git add <文件>..." 以包含要提交的内容)
test.txt
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
可以看出,当前文件还未提交,git无法控制这个文件,这个时候我们直接删除文件就可以了,工作区又会变得干净
$: git status
位于分支 master
无文件要提交,干净的工作区
已经将创建的文件提交到了暂存区
我们不仅创建了文件,还提交到了暂存区
$: git add test.txt
$: git status
位于分支 master
要提交的变更:
(使用 "git reset HEAD <文件>..." 以取消暂存)
新文件: test.txt
如果我们要删除这个文件,请先使用git reset HEAD <filename>
将暂存区清空,然后再使用rm <filename>
删除文件
如果你先删除文件,那么你的暂存区就会出现这种情况
$: git status
位于分支 master
要提交的变更:
(使用 "git reset HEAD <文件>..." 以取消暂存)
新文件: test.txt
尚未暂存以备提交的变更:
(使用 "git add/rm <文件>..." 更新要提交的内容)
(使用 "git checkout -- <文件>..." 丢弃工作区的改动)
删除: test.txt
我并不清楚这种情况是怎样的,添加和删除同时在暂存区中,这是很奇怪的
已经将文件提交到了分支上
这是最经常使用的场景,首先创建一个文件提交
$: touch test.txt
$: git add test.txt
$: git commit -m "add test.txt"
[master 49f5e95] add test.txt
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test.txt
正常情况下我们会使用rm test.txt
直接删除文件
$: rm test.txt
$: git status
位于分支 master
尚未暂存以备提交的变更:
(使用 "git add/rm <文件>..." 更新要提交的内容)
(使用 "git checkout -- <文件>..." 丢弃工作区的改动)
删除: test.txt
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
但是在git中,如果要删除版本库文件,就需要使用git rm <filename>
,并且将其git commit
提交
$: git rm test.txt
rm 'test.txt'
$: git commit -m "remove test.txt"
[master 8abbda3] remove test.txt
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 test.txt
这个时候文件就从版本库中删除了,也就是说我们完全不必要使用rm test.txt
命令,而是直接使用git rm test.txt
命令就已经会删除版本库中的文件和工作区中的文件