git

创建本地Git仓库基本指令

教会你如何在本地优雅地使用git

Posted by kevin on March 25, 2019

前言

最近由于个人因素,需要对git进行更深入的了解,所以写了这系列的教程复盘,一方面增强记忆,一方面忘了的时候也可以回来翻翻笔记。其中内容是参考《Pro Git》这本书,之前入门看的是廖雪峰大大的博客,谢谢这些大牛无私的奉献。

配置用户信息

下载完git之后要做的第一件事就是配置好用户名和邮件地址

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

使用--global选项全局配置,以后使用git时都会使用这些信息,当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有--global选项的命令来配置。

想查看全局配置的话可以使用 git config --list来列出所有的配置

$ git config --list
http.sslcainfo=F:/Git/mingw64/ssl/certs/ca-bundle.crt
http.sslbackend=openssl
diff.astextplain.textconv=astextplain
...

也可以通过git config <key>来获得某一项配置

$ git config user.name
Yarkable

创建仓库

初始化一个空仓库

在一个文件夹中使用git init命令,这时文件夹中就会多出一个.git文件夹,不要随便动里面的东西,这里面包含了git仓库的配置信息。

从网上克隆一个仓库

假如你觉得GitHub上有个项目不错,想看看他的源码,可以使用git clone [url]命令将这个仓库克隆到本地,假如你想克隆的仓库url为https://github.com/libgit2/libgit2,那么可以使用如下命令克隆

$ git clone https://github.com/libgit2/libgit2

然后再本地就会多出一个名字为libgit2的仓库,里面的.git文件夹包含了这个仓库所有的信息。

如果想给文件夹换个名字可以在克隆的时候加上一个参数

$ git clone https://github.com/libgit2/libgit2 mylibgit

这样子的话仓库名字就变成了mylibgit

追踪文件的变化

检查当前文件状态

git仓库文件的状态一般有下面几种

git文件的状态变化周期

如果文件没有被git追踪的话状态为Untracked,一旦将文件添加至git管理之后,文件就处于暂存区(stage)。只要文件被改变(增删改),状态都会变成Modified,如果暂存区的文件很干净没有改动,则可以用commit将其送入版本库.git

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   package.json
        modified:   shells/chrome/manifest.json

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        package-lock.json

no changes added to commit (use "git add" and/or "git commit -a")

用这个命令就会输出当前文件的状态,如果嫌弃输出太多太长了的话,还可以用git status -s或者git status short输出精简版的信息

$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt

??表示未跟踪的文件,M表示文件在工作区被改动,A表示刚跟踪的文件,MM表示文件已经在工作区提交到暂存区后又在工作区被修改了

同时还有一个git status -v选项,可以将两次快照的不同之处输出在编辑器中

跟踪新文件

在git仓库中,其实文件可能会处于三种情况,如果没被git追踪的话那么文件就在工作区(working directory),一旦被追踪就到了暂存区(stage),然后等待被commit提交进新版本库

git几种情况

仓库里面的文件默认是没有被git跟踪的,所以我们要将需要的文件添加至git跟踪文件

$ git add *.c

这样我们就将文件夹中所有的.c文件添加至git跟踪了,如果文件太多可以直接用git add --all,并且git选项一般都支持通配符,节省了开发人员很多时间。不过要注意,git add 添加的是文件的修改,并不是文件本身的内容,为什么这样说,下面你就明白了。

用了git add命令之后文件就处于暂存区了,此时如果再次修改了文件,使用git status还会看到文件被Modified的输出,所以还要再用git add [file]指令将文件添加至暂存区,也就是说,只要有了变动,就得重新add。

忽略文件

如果仓库里有不想被追踪的文件的话,每次使用git status都会输出一片红色的信息,看的很烦,所以我们可以在仓库的根目录下新建一个.gitignore文件,将不想追踪的文件添加进去,以后用git status就不会再输出有关信息了,关于.gitignore文件的内容,有以下一些标准

  • 所有空行或者以 # 开头的行都会被 Git 忽略。
  • 可以使用标准的 glob 模式匹配。
  • 匹配模式可以以(/)开头防止递归。
  • 匹配模式可以以(/)结尾指定目录。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反

下面是一个.gitignore文件的内容

# no .a files
*.a
# but do track lib.a, even though you're ignoring .a files above
!lib.a
# only ignore the TODO file in the current directory, not subdir/TODO
/TODO
# ignore all files in the build/ directory
build/
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
# ignore all .pdf files in the doc/ directory
doc/**/*.pdf

如果代码中会有一些中间编译产物,我们应该养成良好的习惯,在创建仓库的时候就添加上.gitignore文件,网上已经有很多现成的,直接用就行了。

提交更新

如果暂存区很干净等着被提交,我们可以用git commit命令来进行提交,但之前最好用git status检查一下暂存区是否干净,输入git commit之后会进入编辑器界面,此时要你输入一些东西对此次提交做出说明,略显麻烦,我们一般用下面的语句提交

$ git commit -m "<commit>"

这样就直接将此次提交说明和命令集成在一句话里,commit里面要说这次提交更改了什么东西之类的,方便之后回退版本和查看日志。

之前说了,提交之后如果又修改了文件,再次提交时又得

$ git add [file]
$ git commit -m "<commit>"

有点麻烦,所以git提交时有个跳过暂存区的选项 -a,表示将所有已经追踪的文件都暂存起来并进行提交

$ git commit -a -m "<commit>"

移除文件

在git里,如果文件已经添加至暂存区,可以用git rm <file>来将文件从暂存区移除并且在本地的工作目录中删除,然后文件再也不会被追踪了

假如你是直接在本地将文件删除了而不是在git中,那么删除之后git仓库的status会输出一条 “Changes not staged for commit” ,此时需要手动加上下列语句完成此次删除

$ git rm <file>
$ git commit-m "<commit>"

如果我们只想让文件不被git追踪,不想再工作目录中删除,那么可以用下面指令

$ git rm --cached <file>

想强制删除文件可以用git rm -f <file>,就跟Linux下删除是同一个命令,并且支持正则表达式

重命名文件

像Linux一样的命令,用mv命令就可以给文件重命名了

$ git mv file_a file_b

查看提交历史

当从网上克隆了一个仓库或者在本地提交了若干次变化之后,想要查看这个仓库都经历过哪些变动,可以用git log这个命令

$ git log
commit eadf57f63809fa07751ec28d158e9c6cfc01f4cb (HEAD -> master, blog/master)
Author: Yarkable <33142987+Yarkable@users.noreply.github.com>
Date:   Sat Mar 23 01:51:27 2019 +0800

    upload second post

commit 9d0f576146029e39393b51f2954c4a87e9c6752e (origin/master, origin/HEAD)
Author: kevin <kevin_szu@foxmail.com>
Date:   Mon Mar 18 23:18:19 2019 +0800

    change params
commit eadf57f63809fa07751ec28d158e9c6cfc01f4cb (HEAD -> master, blog/master)
Author: Yarkable <33142987+Yarkable@users.noreply.github.com>
Date:   Sat Mar 23 01:51:27 2019 +0800
...

以上就输出了所有提交的信息,是不是觉得这些很乱?注意,log有很多强大并且常用的选项帮助我们更好的格式化输出这些信息。

git log常用的选项

限制 git log 输出的选项

并且,还有个更牛逼的命令git reflog会将你仓库所有的变动都列出来,并且十分精简,谁用谁说好

查看版本间的不同

$ git diff

我们用不加参数的git diff来对比 未暂存的文件 和上次快照(暂存)的不同之处,注意了,这个指令只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动,所以如果仓库中的文件全部被暂存了,那么将会什么都不输出。

若要查看已暂存的将要添加到下次提交里的内容,可以用 git diff --cached命令

命令总结

这里我把这一篇提到的命令都写在了下面方便查阅

$ git config --global user.name "John Doe" 配置用户信息
$ git config --global user.email
$ git config --list			显示用户信息
$ git config user.name
$ git init					初始化仓库
$ git status				查询仓库状态
$ git status -s
$ git add					添加文件进暂存区&追踪文件
$ git commit -m "<commit>"	对提交做出说明
$ git commit -a -m "<commit>"
$ git rm <file>				删除文件并且在本地删除
$ git rm --cached <file>	删除文件但不在本地删除
$ git mv file_a file_b		重命名文件
$ git log					查询改动日志
$ git reflog				查询所有的变动日志
$ git diff					查询变动
$ git diff --cached