Git使用详解

#Git分布式版本控制系统#

git的三棵树:工作区、暂存区、版本区(代码仓库)

#Git的诞生#

林纳斯·托瓦兹在1991年创建了开源的Linux,Linux系统已经发展了十年了,代码库之大让林纳斯很难继续通过手工方式管理了,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!

# 集中式 vs 分布式#

集中式:版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。

分布式:分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。


#安装Git#

Mac自带git,Windows需要自己安装git。安装完成后,还需要一步设置在命令行输入:

```

git config --global user.name "Love Vinci"

git config --global user.email "2316693281@qq.com"

```

#创建版本库#

理解成这个目录里面的所有文件都可以被git管理起来。创建一个文件夹,命令行进入到这个文件夹:

```

mkdir repol(文件夹的名字)#创建repol目录

cd repol                                  #进入到repol目录

pwd                                        #显示当前目录的路径

ls                                              #显示当前目录的内容

然后把这个目录变为Git可以管理的目录

```

git init  #git初始化

```

#把文件添加到代码仓库#

在repol这个文件里,创建一个名字叫做a.txt的文件。里面写点内容,如111。

第一步,用命令git add 告诉git,把文件添加到仓库

```

git add a.txt

```

第二步,用命令git commit 告诉git,把文件提交到仓库

```

git commit -m "提交日志"

```

#继续工作#

把a.txt的内容改为222

```

git status #查看状态

git add:恢复

git checkout 提交

```

》Changes not staged for commit  指有些文件做了改动,但是还没有被提交。

git status 执行完后,提示信息中,告诉我们有些文件做了改动,但是还没有提交,然后建议我们使用add提交,或者使用checkout撤销修改。

如果想看到某个文件具体的改动,可以使用diff命令。

```

git diff a.txt  #查看哪些内容发生了变化

```

我们把刚才修改过的文件添加一下。

```

git add a.txt

```

然后再次看它的状态

```

git status

```

这回提示的是没有改动的文件,即仓库里和本地的文件都一致了。

#版本回退#

log命令显示从最近到最远的提交日志

```

git log

```

如果嫌弃输出的内容太多,可以加参数,简化输出。

```

git log --pretty=oneline

```

看到的一大串类似3628164...888e的是commit id  (版本号)

在git中,用HEAD表示当前版本,上一个版本就是HEAD\land ,上上版本就是HEAD^ \land ,当然在往上100版本写100\land 比较容易数不过来,所以写成HEAD~100

```

git reset --hard HEAD^

```

然后查看a.txt的内容,发现果然回退到上一个版本。

然后继续使用log查看

```

git log

```


发现撤销前的那个版本竟然看不到了,即想回也回不去,怎么办?

只能想办法找到版本号(如果命令行窗口未关闭的话)

```

git reset --hard  63300dca594

```

版本号没必要写全,前几位就可以的,git会自动寻找。当然也不能只写前一两位,因为git可能会找到多个版本号,就无法确定是哪一个了。

如果已经回退到了某个版本,如果想知道回退前的版本号,可以使用reflog找到版本号。

Git提供了一个命令git reflog用来记录你的每一次命令

```

git reflog

```

#工作区和暂存区#

#工作区(Working Directory)#

就是你在电脑里能看到的目录,比如我的repol文件夹就是一个工作区。

#版本库(Repository)#

工作区有一个隐藏的目录.git,这个不算工作区,而是Git的版本库。

git的版本库里存了很多东西,其中最重要的就是称为stage(或叫做index)的暂存区,还有git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。

前面写到把文件往git版本库里添加的时候,是分两步执行的:

第一步用git add把文件添加进去,实际就是把文件修改添加到暂存区;

第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

因为我们创建git版本库时,git自动为我们创建了唯一一个master分支,所以现在git commit就是往master分支上提交更改。

#撤销修改#

#状态1#

继续对a.txt的内容进行修改,然后保存文件,不要进行add 和commit。

在命令中,使用checkout可以撤销修改。

```

git checkout -- a.txt  #注意文件名和--之间有空格

打开文件,就发现内容被撤销了

```

#状态2#

如果是对文件内容修改后,已经执行了add,那么撤销就应该用reset了。

```

#先把暂存区的修改回退到工作区

git reset HEAD a.txt 

#然后撤销工作区的修改

git checkout -- a.txt

```

#状态3#

如果是对文件内容修改后的,已经执行了add,并且已经执行了commit,那么撤销应该这样做:

```

git reset --hard HEAD^

```

#删除文件#

把刚才的a.txt删除掉,然后在命令行中输入git status 能够看到已经删除文件的提示。如果我们想把已经删除的文件还原回来,可以使用checkout

```

git checkout -- a.txt

```

如果我们确定删除这个文件,那么就要保证工作区和版本库一致

```

git rm a.txt  #版本库中删除a.txt

```

###小结

命令|示例|作用

---|---|---

init| git init | 初始化git

status| git status | 查看版本库状态

add| git add a.txt | 把a.txt文件由工作区添加到暂存区

commit| git commit -m "日期" | 把暂存区文件,提交到代码仓库中

diff| git diff a.txt | 查看a.txt发生了哪些变化

log| git log --pretty=oneline | 从最近到最远的提交日志

reflog| git reflog | 用来记录你的每一次命令

reset| git reset --hard HEAD^ | 回退到某一个版本(代码仓库->工作区)

reset| git reset HEAD a.txt | 先把暂存区的修改,回退到工作区(暂存区->工作区)

checkout| git checkout -- a.txt | 撤销a.txt文件的操作(工作区->工作区)

rm| git rm a.txt | 版本库中删除 a.txt

这里,本地的代码仓库全部搞定了。

# 远程代码仓库#

如果我们希望这个项目的版本仓库,本地有一套,网络上也有备份的话,我们需要怎么做?

# GitHub#

账号:lovss             密码:qqwenqi77521

# 第1步#

创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有 id_rsa 和 id_rsa.pub 这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:

```

ssh-keygen -t rsa -C "2316693281@qq.com"

```

你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。

如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。

# 第2步#

登陆GitHub,打开“Account settings”,“SSH Keys”页面:

然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容,点“Add Key”,你就应该看到已经添加的Key。

# 添加远程代码仓库#

首先,登录 GitHub,然后右上角找到 Create a new repo,创建一个新的代码仓库。

> 我的账户名是wangyang1025,邮箱是550759049@qq.com,密码保密。

创建成功之后,根据 GitHub 的提示,在本地的 repo1 下执行

```

# 把本地仓库与网络仓库相关联

git remote add origin 2316693281@qq.com:lovss/sovl.git

```

注意要把 wangyang1025 换成你自己的 GitHub 账户名

下一步,就可以把本地库的所有内容推送到远程库上:

```

git push -u origin master

```

> 传输速度的快慢受限于网络和文件大小

推送完毕后,回到 GitHub 中,就能够看到相应的文件了。

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

只要本地作了提交,就可以通过命令:

```

git push origin master

```

把本地master分支的最新修改推送至GitHub

#SSH警告#

当你第一次使用Git的clone或者push命令连接GitHub时,会得到一个警告:

```

The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.

RSA key fingerprint is xx.xx.xx.xx.xx.

Are you sure you want to continue connecting (yes/no)?

```

这是因为Git使用SSH连接,而SSH连接在第一次验证GitHub服务器的Key时,需要你确认GitHub的Key的指纹信息是否真的来自GitHub的服务器,输入yes回车即可。

Git会输出一个警告,告诉你已经把GitHub的Key添加到本机的一个信任列表里了:

```

Warning: Permanently added 'github.com' (RSA) to the list of known hosts.

```

这个警告只会出现一次,后面的操作就不会有任何警告了。

#把远程代码仓库克隆到本地#

命令行进入到本地的 test 文件夹中。

```

git clone git@github.com:wangyang1025/repo_test.git

```

就会在 test 目录下,把 github 的 repo_test 拿下来了。

然后就可以直接使用 git 了。( 无需 git init )

## 分支

# 创建与合并分支#

我们创建dev分支,然后切换到dev分支

```

git checkout -b dev

```

git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:

```

git branch dev  # 创建dev分支

git checkout dev # 切换到dev分支

```

用git branch命令查看当前分支

```

git branch

```

git branch命令会列出所有分支,当前分支前面会标一个*号。

然后,我们就可以在dev分支上正常提交。

对某文件进行更改后,提交。

```

git add 1.txt

git commit -m "分支测试"

```

dev分支的工作完成,我们就可以切换回master分支。

```

git checkout master

```

命令行切换到不同的分支时,我们的文件也会有对应的变化。

现在,我们把dev分支的工作成果合并到master分支上:

```

git merge dev

```

git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。

注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。

合并完成后,就可以放心地删除dev分支了:

```

git branch -d dev

```

删除后,查看branch,就只剩下master分支了

```

git branch

```

# 小结#

命令 | 示例 | 作用

---|---|---

branch | git branch | 查看分支

branch | git branch dev | 创建 dev 分支

checkout | git checkout dev | 切换到 dev 分支

checkout | git checkout  -b dev | 创建 dev 分支,并切换到 dev 分支

merge | git merge dev | 合并某分支到当前分支

branch | git branch -d dev | 删除 dev 分支

# 解决冲突#

创建 dev2 分支

```

git checkout -b dev2

```

修改 1.txt 的内容

在 dev2 分支中,提交 1.txt

```

git add 1.txt

git commit -m 'dev2'

```

切换到 master 分支

```

git checkout master

```

修改 1.txt 的内容

在 master 分支中,提交 1.txt

```

git add 1.txt

git commit -m 'master'

```

现在,master 分支和 dev2 分支,分别有新的提交。

这种情况下,Git无法执行快速合并。

```

git merge dev2 # 将 dev2 合并到 master 分支中

```

命令行提示冲突了,告诉我们需要手动解决冲突,然后提交。

也可以使用 status 查看哪些文件有冲突。

```

git status

```

也可以直接查看 1.txt 的内容

```

<<<<<<< HEAD

master

=======

dev2

>>>>>>> dev2

```

需要我们手动对 1.txt 文件进行更改后,重新提交

```

git add 1.txt

git commit -m '手动更新'

```

最后,删除 dev2 分支

```

git branch -d dev2

```

工作完成

git 当然还有其他一些功能,如果感兴趣可以去官网自行查阅。

另外推荐一个学习git的网址:https://www.yiibai.com/git/git-quick-start.html(单纯觉得不错,不是打广告!!!)

还有大家如果觉得命令行使用太麻烦可以考虑下SourceTree这款软件~~~~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • Git的配置 Git提供了一个叫做git config的工具,专门用来配置和读取相应的工作环境变量。这些变量可以存...
    code希必地阅读 398评论 0 0
  • 文章内容参考:廖雪峰Git教程 Git命令: Git 命令使用: 默认使用visual studio code g...
    油菜又矮吹阅读 623评论 0 0
  • 说到Git,必须要先谈一下版本控制。什么是版本控制?我为什么要关心它呢?版本控制是一种记录一个或若干文件内容变化,...
    voQuan阅读 1,603评论 0 2
  • 代码管理工具之Git 一,什么是版本控制? 版本控制透过文档控制(documentationcontrol)记录程...
    我的头好大呀呀呀阅读 1,532评论 0 1
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,520评论 28 53