git

透彻讲解git使用

深入git命令行使用

Posted by John Mactavish on August 10, 2019

前言

  之前一直只会commit和push,暑假的时候第一次做了多分支开发,第一次参与他人项目,发起了pull request。暑假就要结束了,按照计划,是时候深入了解一下Git了。

Git基础

  Git的本地仓库和远程仓库是独立的,但是通常将它们关联起来开发。Git 本地仓库有三大区域:工作区、暂存区(stage或index)、版本区。工作区就是在电脑里能看到的目录。暂存区一般存放在 “.git目录下” 下的index文件(.git/index)中。工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
  HEAD默认是目前branch的最新的commit,当然也可以人为修改它。创建远程仓库时远程主机名默认为origin,那么origin/master指的就是远程仓库的master分支。这个主机名其实就是一个变量,它的值就是仓库地址,例如 git push origin master 完全等于 git push git@github.com:username/reponame master 。

Git用户信息

git config –global user.name “John Doe” git config –global user.email johndoe@example.com   用了--global 选项,更改的配置文件就是位于你用户主目录下的那个隐藏文件 .gitconfig ,以后你所有的项目都会默认使用这里配置的用户信息。配置文件也是可以直接手动修改,但是建议使用命令行。

Git初始化

  可以使用git init;但是建议直接借助Github,在上面新建库存,git clone下来,这样本地仓库就默认关联远程仓库了。本地仓库和普通文件夹的主要区别在于里面的.git文件夹。

Git提交和查看

git add命令可将文件添加到暂存区,并跟踪此文件,可以使用 git add . 命令全部添加到暂存区。

使用 git status 命令可查看暂存情况,可以看到工作区中已跟踪文件和未跟踪文件。

git diff,它可以用来查看工作区被跟踪的文件的修改详情。当工作区有改动的时候,暂存区为空(没有进行git add),那么diff是和上次的commit的记录进行对比的;当工作区有改动,暂存区有东西的时候,diff是和暂存区进行比较的。

注意,被跟踪的文件必须要有修改。所以,git add之后立刻查看是没有反应的;但是git add之后修改一下add过的文件就有信息了。

git commit 命令把暂存区的修改提交到版本区,生成一个新的版本,一个必须的选项 -m 用来提供该提交的备注。产生的十六进制序列号就是提交版本号,这是很重要的信息,每个提交都有自己单独的版本号。

git log,它用来查看版本区的提交历史记录。

  • git log [分支名] 查看某分支的提交历史,不写分支名查看当前所在分支。
  • git log –oneline 一行显示提交历史
  • git log -n 其中 n 是数字,查看最近 n 个提交
  • git log –author [贡献者名字] 查看指定贡献者的提交记录

git branch -avv,它用来查看全部分支信息。

Git版本回退

  执行 git rm --cached [文件名] 命令即可撤销暂存区的修改(unstaging)。

git reset [ –soft | –mixed | –hard] [版本号]

  git reset [版本号] 的意思就是 把HEAD移到[版本号]。如果记不清版本号,可以通过git reflog查询。但是一般不用版本号,git reflog返回的信息包含版本序号,执行 git reset HEAD@{n} 命令,意思是回到当前分支最近n次变化前。更常用的是git reset HEAD^ 撤销最近的一次提交,HEAD^^ 表示撤销两次提交,撤销 n 次可以简写为 HEAD~n

git reflog 查询命令,它会记录自本地仓库创建起所有分支的每一次版本变化。实际上只要本地仓库不被删除,无论如何都能回退到任何地方。reflog 记录只存在于本地仓库中,本地仓库删除后,记录消失。
git reflog 可以查看所有分支的所有操作记录(包括commit和reset的操作),包括已经被删除的commit记录,git log则不能察看已经删除了的commit记录。
所以git reset HEAD@{n} 的n是commit和reset的操作次数,而git reset HEAD~n的n是commit次数。前者可以反悔reset的操作。 当然,这样会让逻辑变得相当复杂,所以前者是一道安全措施而非常用操作。

  • soft就是只动版本区
  • mixed就是动版本区还有暂存区(这个是默认参数)
  • hard就是动版本区、暂存区还有工作区

  所以soft回退版本区,将回退的版本上的修改存入暂存区和工作区。因为有存入暂存区,所以这时候如果发现不需要回退还可以再commit回去,版本就和原来一样。

应用:git reset –soft HEAD~3然后git commit就可以把最近三次的提交变成一次(就是当前这次)

  mixed回退版本区,清空暂存区,将回退的版本上的修改存入工作区。这时候如果发现不需要回退就需要staging然后commit回去,版本就和原来一样。

应用:git reset HEAD [文件名],HEAD移动到HEAD表示版本区不变,但是清空暂存区,所以最后的效果相当于unstaging。

  hard将工作区、暂存区、版本区全部回退,回退的版本上的修改消失。

  回退之后可以继续修改,commit。git status提示

Your branch and ‘origin/master’ have diverged

等信息,意思是本地仓库的 master 分支与远程仓库的 origin/master 分支在提交版本上有了冲突,又叫做提交时间线分叉。因为本地仓库和远程仓库是独立的,退回后,本地退回一次,在退回基础上做了修改;而远程仓库保持push后的状态,即退回前的版本。解决方法是:要么git pull让本地向远程仓库同步,放弃本地修改;要么git push -f强行push,让远程仓库向本地同步,保持本地当前的状态。

参考

精讲git reset(推荐阅读)
title


最后附上GitHub:https://github.com/gonearewe