Wlgls 冲鸭!

Git的基本操作

2019-06-29
Git

感谢廖雪峰大佬的教程,正因为廖雪峰大佬的网站,我才能够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命令就已经会删除版本库中的文件和工作区中的文件