Git常用命令详解

Git常用命令详解

写在前面

  • git是我们常用的VSC(版本控制)工具,很多小伙伴在使用git时只是做简单的提交、克隆、解决冲突、拉取代码、提交代码.这也就是我们所说的常规情况
  • 在可视化图形工具泛滥的今天,如IDE自带的VSC管理工具、totoriseGit使得我们工作效率更高,但同时也让我们偏离了事情的本质(究竟什么是git?)
  • 我一直认为做开发需要一点钻研精神,要具有独立解决git问题的能力就必须充分理解git的运作机制,面向百度编程是治标不治本的做法

基本概念

  • 在真正开始之前我们再简单的讲一下git的几个基本概念
  • 仓库
  • git和svn不同,git本地就维护一个仓库(就好比是svn的远程仓).我们所有的操作都在本地完成,也只影响本地的仓库内容,直到我们将它上传到远程仓库
  • 工作流
  • git的本地仓库由git维护的三棵树组成
  • 1.工作目录:工作目录持有实际的文件
  • 2.缓存区(index):缓存区临时保存你的文件改动
  • 3.commit history:提交历史,每一次提交都会生成一个提交号,并存储在树中
  • git的工作流一般是工作目录->缓存区->提交

创建仓库:git init

  • 作为一般的开发人员,是不会去使用这一步的,想想我们是如何获取项目的?一般都是使用git clone.但是我们还是简单的说一说
  • git init有什么作用?
  • 现在让我们新建一个文件夹,就叫做gitlearn吧
  • 打开我们的命令行程序(cmd/bash/terminal),键入如下的命令
    $ git init
    
    Initialized empty Git repository in xxx/Desktop/gitlearn/.git/
    
  • 可以看到 git init命令在我们的gitlearn/.git文件夹下创建了一个仓库,打开我们的gitlearn文件夹.我们发现确实多了一个.git文件夹,原来如此.我们的仓库文件就存在于这个.git的隐藏文件夹下面
  • 总结
  • git init命令在我们当前文件夹下面创建了一个.git隐藏文件夹,该文件夹下面存储的git仓库相关的信息,也正是这个文件夹将我们的gitlearn文件夹标识为一个本地仓库.
    .git文件夹下的内容非常丰富,有许多git实现的核心文件,这里我们就不展开解释了
    

保存工作空间的修改

git add
  • git add的作用就是将我们工作空间中的文件添加到缓存区
  • 下面我们新建一个add.txt文件夹,并将它添加到缓存区
    $ touch add.txt
    	让我们来编辑一下文件的内容:this is a add test file
    $ git add add.txt
    	到这里,我们就向缓存区添加了add.txt文件,我们可以使用git status命令查看
    $ git status
    	On branch master  //指明了我们当前的分支
    	No commits yet  
        Changes to be committed: //说明我们缓存区的文件(可被用于下次提交)
    		(use "git rm --cached <file>..." to unstage)
    			new file:   add.txt
    
    感兴趣的小伙伴可以看一看我们add之前的状态,git会告诉我们当前工作空间还有一个叫做add.txt的文件没有被添加到缓存区.也就是说当前工作空间的改变对我们下次提交是无效的
git commit
  • git commit 将缓存区中的改动提交给本地仓库
  • 下面我们将缓存区的文件提交给本地仓库
    $ git commit -m 'first commit' //-m参数后面跟着我们的commit message
    	[master (root-commit) 19ebc79] first commit
    	1 file changed, 1 insertion(+)
    	create mode 100644 add.txt
    $ git log --oneline //我们使用git log可以查看当前的提交记录,oneline表示显示在一行
    	19ebc79 (HEAD -> master) first commit
    
    注意这里19ebc79是一个简短的提交号,我们可以通过git log查看完整的提交编号
    
临时文件存储:git stash
  • git提供了一个栈空间,让我们临时存储文件
  • 什么时候需要临时存储?
  • 当我们开始一个提交时,工作空间是不可以有非缓存区文件的,所以当我们修改了某个文件,但并不想在本次提交中提交时,我们需要将该文件放入stash栈缓存栈中
  • 试想一下我们有以下情形
    1.开发工作做到了一半,开发组长突然让我们修改一个紧急bug.我们该怎么做?
      注意:如果你说先将当前分支的内容提交.的确是一种解决办法.但是不符合提交的定义,这不是一次规范的提交
      1)先将工作空间的文件add到缓存区,将缓存区的文件存入stash栈
      2)修改Bug,提交,push到远程分支
      3)将stash栈中的内容弹出到缓存区和工作空间
    2.开发到一半,突然发现写错分支了.我们应该在myBranch上开发,而不是当前的dev分支,怎么办?
      1)将工作空间的文件add到缓存区,将缓存区的文件存入stash栈
      2)checkout myBranch
      3)将stash栈中的内容弹出到缓存区和工作空间
    
  • 这样看来我们的stash栈是非常有用的
  • git stash的使用
  • git stash save [ “message”] :将缓存区和工作空间的文件存到栈中
    $ touch stash.txt //先创建一个新的文件
    $ git add stash.txt //加入缓存区
    $ git stash save //将缓存区即工作空间中对应的文件放到栈中
    Saved working directory and index state WIP on master: 19ebc79 first commit
    $ ls 
    add.txt //你发现了什么?我们的stash.txt不见了.只剩下之前commit的add.txt文件
    
    注意:如果工作空间中的文件没有加入到缓存区,是不会放入stash栈中的
    
    • git stash list:查看当前的stash list
    $ touch stash2.txt stash3.txt
    $ git add stash2.txt stash3.txt
    $ git stash save
    Saved working directory and index state WIP on master: 19ebc79 first commit
    $ git stash list
    stash@{0}: WIP on master: 19ebc79 first commit //第一次保存:stash.txt
    stash@{1}: WIP on master: 19ebc79 first commit //第二次保存:stash2.txt和stash3.txt
    我们可以看到栈中有两次保存,第一次保存在栈底,第二次保存在栈顶
    注意.第一次保存是stash.txt一个文件
            第二次保存是stash2.txt和stash3.txt两个文件
    此时我们的文件夹中就只剩下add.txt了
    
    • git stash pop:弹出一次保存,当我们弹出一次保存时,栈中的这次保存就不存在了,文件再次回到了缓存区和工作空间
    $ git stash pop
    on branch master
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
    	new file:   stash2.txt
    	new file:   stash3.txt
    Dropped refs/stash@{0} (274c98c093d0f8eb65774c4b5fd4809b170228d9)
    $ git stash list //再执行一次看看
    stash@{0}: WIP on master: 19ebc79 first commit
    $ ls //可以看到栈顶的存储内容又回到了工作空间和缓存区
    add.txt   stash2.txt stash3.txt
    
  • git stash apply [@{编号}]:使用某次保存,但不会从栈中弹出,这适用于多个分支需要使用相同的文件的情形.如果不带编号.默认使用编号0
     $ git stash apply
     $ git stash list
     stash@{0}: WIP on master: 19ebc79 first commit
     $ ls
     add.txt   stash.txt  stash2.txt stash3.txt
     我们可以看到stash栈中的第一次存储没有被丢弃,但是stash.txt已经回到了工作空间和缓存区
    
  • git stash drop:丢弃栈中的所有存储

查看仓库状态

git status
  • 之前我们已经介绍过git status的用法
  • git status是一个相对简单的命令,它告诉你git add和git commit的进展,status信息中还包含了添加缓存和移除缓存的相关指令
git log
  • git log 用于查看我们的提交日志,常用的命令如下
  • 1.git log :使用默认格式显示完整的项目历史
  • 2.git log -n <limit> : 只显示最近的前次提交
  • 3.git log --oneline: 将每个条信息压缩到一行,便于查看

前面我一共做了3次提交,第一次是first commit
第二次是将stash中的第二次存储pop出,提交了stash2.txt和stash3.txt
第三次是将stash中的编号0存储apply,提交了stash.txt

$ git commit --oneline
efbc959 (HEAD -> master) stash.txt
fa5447e stash2&3
19ebc79 first commit
检出之前的提交
  • 检出(checkout):在git中有三个不同的作用
  • 1.检出文件
  • 2.检出提交
  • 3.检出分支
  • 在本节中我们只讲前两个应用
git checkout
  • 检出提交:git checkout <commit>
  • 检出某个分支可以让我们进入detached HEAD模式,该操作其实是创建一个临时分支,然后将HEAD分支定位到我们要检出的分支上.在临时分支上做的所有修改、提交都不会影响到主分支,如果我们要保存临时分支上的提交,需要将临时分支检出到一个新的分支上,可以使用git checkout -b <new-branch-name>
    $ git checkout fa554e //我们之前通过git log查到,该分支是倒数第二次提交
    Note: checking out 'fa5447e'
    ... 省略了一堆提示...
    HEAD is now at fa5447e stash2&3
    $ git branch //查看所有分支的情况,发现我们在一个临时分支上
    * (HEAD detached at fa5447e)
    master
    $ touch detach.txt
    $ git add detach.txt
    $ git commit detach -m 'detach'
    $ git branch -b detach //我们将临时分支的提交保存在临时分支detach
    Switched to a new branch 'detach'
    
    !!注意:如果我们直接切换到一个已有的分支,所有的commit将会被丢弃!!
    
    $ git log --oneline //再查看我们的日志,发现提交日志已经改变了
    113abb1 (HEAD -> detach) detach
    fa5447e stash2&3
    19ebc79 first commit
    
    !!注意:此时只是改变了我们detach的提交记录,master(假设我们之前就在master上开发)的提交记录是不变的
    
  • 检出文件:git checkout <commit> <file>
  • 检出某个提交的某个文件
  • 如果不带commit id,则检出缓存区的文件,如果暂存区为空,指定的文件会回到上一次提交的状态,我们可以利用这个特性来回滚对某个文件的修改
  • 总结
  • 1.checkout <commit>不会改变当前分支的提交状态,这是因为git要保证数据的完整性,checkout 提交只是给了我们回溯到某次提交的能力.在此基础上我们可以另起分支在这个提交节点之后继续开发

回滚错误的修改

  • 我们常常面临这样的问题:我错误的提交了某个快照,我该如何撤销他?
git revert(撤销)
  • 撤销操作常常用来移除一整个提交
  • git revert <commit> -m ‘描述’
    $ touch wrong.txt
    $ git add wrong.txt
    $ git commit -m 'someting wrong'
     [master 502884e] someting wrong
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 wrong.txt
    $ git log --oneline //让我们来查看master上的提交
     502884e (HEAD -> master) someting wrong
     efbc959 stash.txt
     fa5447e stash2&3
     19ebc79 first commit
    $ git revert 502884e
     1 file changed, 0 insertions(+), 0 deletions(-)
     delete mode 100644 wrong.txt
    $ git long --oneline //让我们再来看看master上的提交
     7c02632 (HEAD -> master) Revert "someting wrong"
     502884e someting wrong
     efbc959 stash.txt
     fa5447e stash2&3
     19ebc79 first commit
    

是不是和你想的不太一样?git revert并没有撤销我们的提交记录,而只是撤销了某一次提交的内容并作了一次新的提交

git reset(重设)
  • 重设往往用于移除一系列提交
  • 如果说revert是安全的回滚,那么reset是一个危险的回滚
  • reset操作将HEAD移动到某个版本,并将之后的提交全部清除
  • 1.git reset <file> :从缓存区移除特定文件,但不改变工作目录
    $ touch reset.txt
    $ git add reset.txt
    $ git status
     On branch master
     Changes to be committed:
        (use "git reset HEAD <file>..." to unstage)
    			new file:   reset.txt
    $ git reset reset.txt
    On branch master
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    		reset.txt
    可以看到 git reset 清空了 缓存区的rest.txt文件,它现在仅存在于工作区中
    
  • 2.git reset :重设缓存区,匹配最近一次提交.所有 之后的更改会保留在工作目录中,这允许你用更干净、原子性的快照重新提交项目历史。
  • 3.git reset --hard <commit>:将当前分支的末端移到 <commit>,将缓存区和工作目录都重设到这个提交。它不仅清除了未提交的更改,同时还清除了 <commit> 之后的所有提交。
    现在我们要重置到第一次提交
    $ git log --oneline
     7c02632 (HEAD -> master) Revert "someting wrong"
     502884e someting wrong
     efbc959 stash.txt
     fa5447e stash2&3
     19ebc79 first commit
    $ git reset --hard 19ebc79
     HEAD is now at 19ebc79 first commit
    $ git log --oneline
     19ebc79 (HEAD -> master) first commit
    $ ls
     add.txt
    

我们的提交记录都不见了,工作区也只剩下add.txt.所以一定要慎用reset 命令

git clean
  • git clean用于清理未跟踪(也就是工作区但未加入缓存)的文件
  • git clean后的文件不可恢复,也需要慎用
总结
  • 1.reset 会改变提交记录,所以我们一定要慎用,尤其是已经提交到公共仓的commit一定要禁用reset
  • 2.revert是更加安全和灵活的回滚方式

结语

  • 以上就是git常用的命令,这里我没有加入分支的部分(我承认.是我偷懒了),但分支是我们常用的基础功能,大家应该没有什么疑问.
  • 要掌握git的工作原理,最主要的就是要弄清楚git的工作流:工作空间、缓存区、提交树

参考文章

  • 1.https://github.com/geeeeeeeeek/git-recipes 大神写的比我要好得多,大家可以参考,只不过我的这篇文章细节更加丰富
  • 2.https://www.cnblogs.com/zndxall/archive/2018/09/04/9586088.html
  • 3.https://www.cnblogs.com/0616–ataozhijia/p/3709917.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值