Git常用命令总结 Git常用命令总结

想要学会使用Git,首先需要理解什么是分布式版本库,什么是工作区和暂存区,这几个概念是理解很多命令的基础。强烈推荐阅读廖雪峰老师写的Git教程,这是目前为止最好的中文Git教程,没有之一。如果你想要成为Git专家请参考《Pro Git》(Second Edition)

先简单地解释一下工作区、版本库和暂存区。看不懂没关系,先了解下后面的git addgit commit命令后再看就容易理解了。(如果还是没有明白,点这里。)

  • 工作区:你的工作目录,你的工程文件夹。
  • 版本库:就是你工作区中的.git文件夹,这里忠实地记录着你提交过的每一次改动。git commit命令就是把你的改动从暂存区提交到了版本库的当前分支,比如默认的master分支。
  • 暂存区:需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。也就是使用git add后文件修改就保存到了暂存区,以备使用git commit命令提交到真正的版本库。

这里只对常用命令做一下梳理,这些命令基本可以满足日常使用,注意所有git命令都要在你项目的根目录下使用。

创建仓库

$ git init

添加到暂存区

创建仓库之后就可以使用git管理当前目录下的代码了。同时该目录下多了一个.git的子目录,用ls -a可以查看。

$ git add filename

把修改添加到暂存区,每次修改后都需要运行git add命令,之前已经add过得文件也一样,如果不add到暂存区,那就无法commit。因为git记录的是修改而不是你文件的拷贝,这也是它可以如高效和节约空间的原因。(使用过git add命令的文件状态就是Tracked,新建的文件状态是Untracked。)

$ git add .

把所有文件添加到暂存区。

忽略某些文件

有些文件我们无需Git管理,也不希望看到它出现在Untracked列表里面,比如使用Vim时产生的.swp临时文件。我们只要创建一个名为.gitignore的文件,列出要忽略的文件模式即可,支持简单地正则表达式(其实是glob模式匹配,shell中使用的简化了的正则表达式)。
看一个《Pro Git》中给的.gitignore文件的例子就懂了:

# 此为注释,会被 Git 忽略
# 忽略所有 .swp 结尾和 .a 结尾的文件
*.a
# 但 lib.a 除外
!lib.a
# 忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
/TODO
# 忽略 build/ 目录下地所有文件
build/
# 忽略 doc/ 目录下的所有 .txt 文件,但不包括 doc/ 子目录中的 .txt 文件
doc/*.txt
# 忽略 doc/ 目录下的所有 .txt 文件,包括 doc/ 子目录中的 .txt 文件
doc/**/*.txt

那些讨厌的临时文件再也不会在git add的时候捣乱,也不会出现在Untracked列表里了。

提交

$ git commit -m "wrote a new file"

把文件提交到版本库,-m后面输入的是本次提交的说明,方便以后从历史记录里找到改动记录。

如果不想每次都要git addgit commit怎么办,有一个简单地办法,使用-a参数:

$ git commit -a -m "I did some work"

这样即使是上次提交之后修改过的文件(Tracked)也可以直接提交到版本库中(当前的分支)。

查看状态

$ git status

查看版本库状态,就是告诉你哪个文件修改已经在暂存区了(to be commit),哪个文件已经add过但是最后的修改没有add(Changes not staged for commit),哪个文件是新建的还没有add过(Untracked)。

查看日志

$ git log

git log命令显示所有提交,从最早的提交到最近一次提交(当前HEAD所指向的提交,请参考版本回退)。

$ git log --pretty=oneline

加上--pretty参数后可以单行输出。

$ git reflog

用来记录你的每一次命令,包括回退命令。

版本回退

在Git中,用HEAD表示当前版本,也就是最新的提交。

$ git reset --hard HEAD^

这个命令表示回退到当前HEAD的上一个版本,也就是舍弃了最后一次提交。会退后再使用git log命令将无法查看最后一次提交的记录,只能看到当前HEAD,以及更早的提交。可以使用git reflog命令查看所有提交记录。

$ git reset fc142e435432984a95b46bb7b757b9bdcee0e8e8

git reset后的参数是通过git reflog查看到的你希望回退到的版本,可以是任意提交过的版本。

撤销修改

$ git checkout -- filename

命令git checkout -- filename意思就是,把filename文件在工作区的修改全部撤销,这里有两种情况:

  • 文件修改后还没有add到暂存区,撤销修改就回到最后一次commit时的状态;

  • 已经add后又作了修改,撤销修改就回到最后一次add时的状态。

如果你乱改了文件还add到了暂存区,想要回到上一次commit时的状态,先使用命令git reset HEAD filename,使暂存区文件恢复到和commit时一致,再使用git checkout -- filename

注意:git checkout -- file命令中的--很重要,没有--,就变成了“创建一个新分支”的命令。

删除文件

直接删除摸个文件,或者用rm filename命令删除,然后使用命令:

$ git rm filename

然后commit 就可以了。如果不小心删错了文件并且没有commit,没关系,冷静一下,使用上面一条命令git checkout -- filename就可以恢复了。

如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。

查看分支

每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。默认分支是master,也是HEAD指向的分支。

$ git branch

前面有*的分支是当前分支。

新建分支

$ git branch branchname

比如git branch dev命令创建了一个叫dev的分支,现在devmaster指向相同的提交。

切换分支

$ git checkout branchname

使用git checkout dev后,HEAD就指向了dev,现在提交的修改就会到dev分支上,而master分支会停留在当前状态。

创建+切换分支

$ git checkout -b branchname

前面两条命令合并成一条。

合并某分支到当前分支

$ git merge branchname

比如当前分支是master,使用git merge dev,会将dev分支上的提交添加到master分支上。这种合并方式是快速合并(Fast-forward)当两个分支都做过修改后合并是可能会产生冲突,无法进行快速合并,当Git无法自动合并分支时,就必须首先解决冲突

删除分支

$ git branch -d branchname

合并完成后,就可以放心地删除dev分支了。合并后再删掉分支,和直接在master分支上工作效果是一样的,但过程更安全。

查看文件差异

$ git diff

比较工作区和暂存区的差异。

$ git diff filename

比较同一个文件在不同分支的差异。

$ git diff branchname

比较当前分支和branchname分支的差异。

$ git diff --cached
// or git diff --staged

比较暂存区和HEAD的差异。

$ git diff --HEAD

比较工作区和HEAD的差异。

解决冲突

git merge命令会标记有冲突的文件内容,使用git status可以查看冲突文件,使用git diff filename可以查看文件内容,比较不同分支上的差异。

打开有冲突的文件,解决冲突,再提交,合并完成。

用带参数的git log --graph可以看到分支的合并情况:

$ git log --graph --pretty=oneline --abbrev-commit

现在,你已经可以使用Git在自己的机器上愉快地玩耍啦^_^。