Git 的正确使用姿势与最佳实践

108 阅读5分钟

初识Git

在加入青训营学习之前,从来没有接触过Git,也不了解Git是干嘛用的。在进行小组组队的时候,我心仪的队伍他们的招人标准就是要会Git,于是我开始意识到这个技术对我来说至关重要,于是我便从网上到处找资料进行学习,现在我来分享一下我的学习过程以及实际运用。

看文档

在网上找了众多的学习资料,都觉得讲的不够深透,直到我发现了廖雪峰老师的文档(www.liaoxuefeng.com/wiki/896043…) 他总结的知识点简单易懂而且没有废话,有的篇章虽然很短但是都是精髓,每个篇章的后面也有对应的他自己使用过程的截图,非常符合我的胃口。

边学习边操作

最开始需要做的是下载Git,我之前因为一些原因已经下载好了,所以这次也没再学了,我也不多说了,我就在这贴个Windows的Git下载地址吧:git-scm.com/downloads

创建版本库

什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

所以,创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录:

$ mkdir GitDemo
$ cd GitDemo
$ pwd 
/e/GitDemo

这样我们就创建好了一个文件夹,但是注意还不能用Git进行管理,接下来需要git init初始化一下,才能把这个目录变成Git可以管理的仓库:

$ git init
Initialized empty Git repository e/GitDemo/.git/

瞬间Git就把仓库建好了,而且告诉你是一个空的仓库,可以发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。

如果你没有看到.git目录,那是因为这个目录默认是隐藏的,用ls -ah命令就可以看见。

git add 和git commit操作

OK现在开始进入正文了,首先咱就来创建一个文本文档来测试,编写一个readme.txt文件,内容如下:

image.png

一定要放在刚刚创建的这个文件夹里面,放其他地方Git是找不到滴。将这个文件放到Git仓库只需要两步。

第一步:用命令git add告知Git,将文件添加到仓库

第二步:用命令git commit -m "xxx"告诉Git,把文件提交到仓库

image.png

简单解释一下git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。

注意:我们完全可以进行多个add操作然后在commit,还有一个就是,我在写项目用到Git的时候,我发现可以使用命令git add .来添加所有的文件到仓库,这样可以减少很多麻烦的语句

版本回退

现在,你已经学会了修改文件,然后把修改提交到Git版本库,现在,再练习一次,修改readme.txt文件如下:

Git is a distributed version control system.
Git is free software distributed under the GPL.

然后尝试提交:

$ git add readme.txt
$ git commit -m "append GPL"
[master 1094adb] append GPL
 1 file changed, 1 insertion(+), 1 deletion(-)

到目前为止我们已经对readme.txt文件进行了两次修改以及提交,次数比较少我们都还记得住,那万一以后修改的次数多了起来,我相信很难记住以前做过什么修改了吧,于是就有了git log命令,可以告诉我们历史记录

image.png

好了,现在我们启动时光穿梭机,准备把readme.txt回退到上一个版本,也就是add distributed的那个版本,怎么做呢?

首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交1094adb...(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

现在,我们要把当前版本append GPL回退到上一个版本add distributed,就可以使用git reset命令:

$ git reset --hard HEAD^
HEAD is now at e475afc add readme

--hard参数有啥意义?我也不知道,但是现在先放心使用。

git status的作用

在使用Git的过程中git status是个很有用的命令,我在实战的时候也用得比较多,因为它会显示有关工作目录和暂存区(索引)中文件的变化信息,帮助你了解哪些文件被修改、添加或删除,并提示你应该执行哪些操作来将这些变化纳入版本控制。

例如我现在修改了readme.txt文件,但是我不进行add操作:

image.png

它会很清楚的提醒我应该进行什么操作

git rm删除功能

在Git中,删除也是一个修改操作,我们实战一下,先添加一个新文件test.txt到Git并且提交:

$ git add test.txt

$ git commit -m "add test.txt"
[master b84166e] add test.txt
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt

一般情况下,你通常直接在文件管理器中把没用的文件删了,或者用rm命令删了:

$ rm test.txt

这个时候,Git知道你删除了文件,因此,工作区和版本库就不一致了,git status命令会立刻告诉你哪些文件被删除了:

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

	deleted:    test.txt

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

现在你有两个选择,一是确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit

$ git rm test.txt
rm 'test.txt'

$ git commit -m "remove test.txt"
[master d46f35e] remove test.txt
 1 file changed, 1 deletion(-)
 delete mode 100644 test.txt

现在,文件就从版本库中被删除了。

远程仓库的连接

现在的情景是,你已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举多得

首先先创建一个GitHub仓库,接下来分两步进行两个仓库的连接

第一步:在本地的仓库下运行如下命令:

git remote add origin git@github.com:Mirrre/GitDemo.git

其中Mirrre是我自己GitHub账户的姓名,记得改成自己的,其次GitDemo是GitHub的仓库名

第二步:添加本地SSH Key到你的账户列表里面去,登录自己的账号,找到settings设置,点击SSH and GPG keys,点击New SSH Key,最后添加本地的SSH即可

image.png 然后,就可以把本地库的所有内容推送到远程库上:

$ git push -u origin master
Counting objects: 20, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (20/20), 1.64 KiB | 560.00 KiB/s, done.
Total 20 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), done.
To github.com:michaelliao/learngit.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。

由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令

基本功能大概就这些,更深入的以后慢慢探索