Git完全入门指南
教程参考
概述
Git是项目版本管控的工具,可以用来追踪,记录文件的变动,无论你是自己一个人做项目还是多人协作项目, 都是十分必要的工具。
git一般用来:
- 备份自己项目中的每一次修改
- 将自己的项目上传到远程服务器和别人一同协作
- 合并自己和别人对同一个项目的修改
- 找回过去的项目版本
笔者会结合自身项目中常用的命令和一个简单的实例一步步来带新手进入git的世界。
Git安装
Ubuntu
一行命令搞定
sudo apt-get install git
Windows
在Git官网上下载安装程序, 按默认选项安装即可,安装完成后在开始菜单中找到git bash
, 说明git安装完成!
安装完成之后要进行设置。设置自己的名字和自己的邮箱。
打开git bash
image.png在git bash命令行中输入
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
--global
表示对该机器上的所有git版本库都使用这个配置。
这里的名字可以比较随意,但邮箱一定要填自己常用的那个,因为之后我们需要用来登录github并提交到github远程服务器。
基本使用
创建git版本库 - git init
配置完成之后我们就要开始在本地创建自己的git版本库了。
我们先进入一个目录并调出git bash
cd D:\\Document\\git-test
git init
现在在git-test文件夹下就多了一个.git
文件夹,这个.git文件夹里面便会去记录我们文件的每一次修改。
查看工作区状态 - git status
我们把现在的除了.git
文件夹的区域称之为工作区, 因为我们的项目就是放在这个目录下的,我需要查看当前工作区的状态则使用git status
命令。
$ git status
On branch master
Initial commit
nothing to commit (create/copy files and use "git add" to track)
这里输出了三行字,我们一行一行来理解
- 当前我们在master分支
- 初始化提交
- 没有文件需要提交
分支
分支是git中的一个概念,可以理解为树中的枝干,而在我们刚创建一个git版本库的时候我们处于的是master分支,也叫主分支,分支的概念在后面会提到。
第一行指我们现在处于的是主分支的开发环境, 第二句话指我们刚刚做了初始化git版本库的操作。第三句话是指当前缓冲区中没有文件需要提交。关于缓冲区这个我们也稍后再说。我们先试着添加一个文件。
$ touch git-test.md
创建一个叫git-test.md的文件,再执行git status
$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
git-test.md
nothing added to commit but untracked files present (use "git add" to track)
前两句话是一样的就不解释了, 第三句话就很重要了,Untracked files, 没有追踪到的文件,
然后下面是git-test.md,也就是我们刚刚创建文件,再下面告诉我们没有添加提交但未跟踪的文件存在,
其实这里就是告诉我们git-test.md还没有在我们的git版本库中,他的修改等不会被git版本库追踪。
那么我们赶紧把git-test.md加入git版本库进行追踪吧。
添加到暂存区 - git add
添加到版本库分为两步,第一步是添加到暂存区,执行下面的指令。
$ git add git-test.md
git add 文件名
即为将文件添加到暂存区了, 如果要添加当前目录下的所有文件用 git add -a
。
再执行 git status
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: git-test.md
发现原来的git-test.md没有被追踪的提示消失了,反而提示 被提交的改变为:新文件: git-test.md
也就是说git版本库已经知道我们创建了一个新的文件了。
接下来还没完,这只是放在暂存区,还没有真正的保存。真正的保存需要用git commit
来确认一次提交
确认提交 - git commit
添加到版本库的第二步是确认提交,确认提交是我们工作进行到一定程度,一般是完成了一个小功能,想保存一下进度的时候做的,这时候我们顺便会记录一下我们做过的工作,所以git commit
一般这么写
$ git commit -m "创建了新文件git-test.md"
[master (root-commit) b989378] 创建了新文件git-test.md
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 git-test.md
-m
即message, 表示提交信息
这里也有3行,主要理解一下前2行:
- master分支下进行了一次提交,提交信息为"创建了新文件git-test.md", 本次提交的版本号为b989378,这个版本号我们也稍后再详细解释
- 提交中有1个文件变化,0个插入,0个删除
很好,这次提交达到了我们想要的效果。
再执行git status
$ git status
On branch master
nothing to commit, working tree clean
这次直接提示我们,没有文件需要提交,工作树是干净的。到此我们的一次工作记录就完成了。
git add 和git commit
git add其实已经将你的修改保存下来了, 为什么还要git commit呢, 用游戏类比的话, add 只是推荐游戏的进行, 但是并没有对游戏存档, 如果我们想要存档,并可能在以后回到这个存档点,我们就需要手动进行一次存档,这就是git commit了。你是没办法回到上一个add的操作点,但是可以回到commit的操作点。回到存档点的方法我们稍后再说。
我们再来一遍相似的操作。首先我们修改git-test.md的文本内容,添加两行字
学习git
hello world
然后我们查看下暂存区和工作区文件的不同。
查看不同 - git diff
我们可以用git diff
来查看git跟踪的文件的变化。
$ git diff
diff --git a/git-test.md b/git-test.md
index e69de29..e13761d 100644
--- a/git-test.md
+++ b/git-test.md
@@ -0,0 +1,3 @@
+学习git
+
+hello world
主要关注最后两行, -0,0
意思是0到0行被删除了,也就是没有行删除。+1,3
意思为1到3行被添加了,添加的内容为学习git
,空行
,hello world
。所以我们用git diff
指令就能看出来我们工作区相对版本库的改变,相对版本库,也就是说是执行了git add
之后的改变(git add即进入版本库的第一步), 你现在可以试试输入git add
之后再输入git diff
,这次就什么都不会输出了。因为工作区和版本库是同步的了。
继续执行commit来确认提交
$ git commit -m "添加了两行文字"
[master a26ff1d] 添加了两行文字
1 file changed, 3 insertions(+)
这里之所以有个空行是因为我用的markdown编辑器在换行的时候会自动插入一个空行。
回到过去 - git log; git reset
存档已经有了,我们该试着读档了。假设我们不小心删掉了第二行hello world
, 但是我们想回到上一个有hello world
的时候。首先我们需要查看我们的存档表。
$ git log
commit a26ff1da8e69bb2afbd386c24c57706f2175852d
Author: Acring <392398434@qq.com>
Date: Mon Mar 26 11:27:24 2018 +0800
添加了两行文字
commit b9893787f3cdadecb17e6c0cce0020b3c5a38256
Author: Acring <392398434@qq.com>
Date: Sun Mar 25 22:30:04 2018 +0800
创建了新文件git-test.md
这里显示了每一次提交的信息,包括
- 提交版本号
- 作者
- 提交日期
- 提交信息
我们需要的是版本号,比如这里的有hello world
的存档的版本号为a26ff1da8e69bb2afbd386c24c57706f2175852d
, 我们也不用全部记住,其实只需要前几位就行了,接下来用git reset
来读档。
$ git reset --hard a26ff
HEAD is now at a26ff1d 添加了两行文字
他告诉我们HEAD(头指针)已经指向了我们的a26ff1d开头的存档了,再看看我们的git-test.md文件,是不是hello world
又回来了。
graph LR
a((b989378))-->b((a26ff1d))
b---c((删除hello world))
h(HEAD)-->c
git中的改变可以看做一条链表,而我们工作处于HEAD(头指针)所指向的那个修改。改变HEAD的位置也就改变了工作区的内容了。
版本回退还有revert checkout 等方法,reset只是相对比较简单的方法,如果有兴趣可以去了解其他的方法,不过版本回退在开始一般用得比较少
无视文件 - .gitignore
在实际项目中有些文件是不需要被提交到git版本库的,比如自己服务器的配置文件(不想开源的时候被人看到), 第三方包文件夹(文件太大,上传太慢)等等,这时候我们就需要用.gitignore文件去过滤掉这些文件或文件夹。
首先新建一个文件.gitignore
不需要后缀, 然后用文本编辑器打开并添加一行,
ignored.md
意思是我们准备无视掉这个叫ignored.md
的文件。 接着我们创建这个ignored.md
文件,里面有没有内容都没关系。
用git bash 执行命令git add ignored.md
$ git add ignored.md
The following paths are ignored by one of your .gitignore files:
ignored.md
Use -f if you really want to add them.
可以看到add失败了,git提示我们当前路径已经被.gitignore文件设定为无视了,无法被add添加到版本库,除非用-f
指令强制执行。有了.gitignore我们就可以放心的用git add -a
添加所有文件了, 因为git会自动把.gitignore中提到的文件或文件夹过滤掉不添加。gitignore的语法规则可以自己去百度,其实还是比较简单的。
以上都是笔者在本地git实践中比较常用的命令了,其实并不多,add commit 是最主要的。
接下来要开始将git搬上远程服务器进行实践了。
注册github
为啥我们要使用github,github是啥?这是我们需要首先明白的问题。
github提供了一个git服务器,这样我们就不需要自己买一台远程服务器了,但是github为你免费提供服务器的代价是你的项目是公开的,如果不想公开的话必须购买付费服务,你可以把自己的开源项目通过git上传到git服务器,并为这个项目创建一个主页用来分享自己开源项目。
使用github首先我们需要到官网注册,注册过程就不多加赘述了,注册完成之后我们需要让github知道我们的计算机是哪台。也就是说我们允许哪台计算机修改这个账号所拥有的开源项目。
github是基于SSH协议来认证计算机的,具体感兴趣可以自己去了解SSH协议, 现在我们只需要知道,我们需要提供一个公钥给github, 这个公钥是在我们本地计算机生成的。
生成方法如下, 进入git bash
$ ssh-keygen -t rsa -C "youremail@example.com"
这里的邮箱改成自己的邮箱。之后一路回车,使用默认值。
注意在生成的过程中会显示他的生成路径, 比如我的是(/c/Users/Acring/.ssh/id_rsa)
, 记住这个地址
之后查看自己计算机的上述的.ssh
路径,但是我们要用的不是id_rsa
,这个是私钥,是不能泄露出去的,我们要用的是id_rsa.pub
公钥,打开之后把里面的字符全选复制。
公钥有了,接下来就是把这个公钥告诉github让github知道我的这台计算机有权利管理github上该账号的项目了。
在github中进入Setting
->SSH and GPG keys
点击New SSH Keys
, 随便输入一个Title用来标识自己的计算机,将刚刚复制的公钥粘贴进去Key里, 点击Add SSH key
保存就行了。
本地和远程同步
接下来我们就要把之前我们编辑的git-test项目上传到github上了。首先我们需要在github上建立一个空的远程git版本库。
image.png按顺序填写版本库信息,点击Create repository
完成创建。
注意上面画圈的地方, 后面的URL是这个远程git版本库的地址,前面是上传项目过程中用的连接协议,我们就选SSH协议,好处是不需要每次上传都输入github账号密码,因为我们已经通过SSH Key
告诉了github我们现在这台计算机是有项目管理权限的。顺便这个地址我们复制下来。马上就要用到了。
远程版本库创建完毕,但是现在本地的版本库还不知道有一个远程版本库哇,我们需要把他们两个关联起来。
回到本地, 在原来的项目git-test目录下打开git bash(如果你在开始菜单打开git bash则会处于用户主目录下,要用cd跳转路径), windows下可以在项目目录中点击鼠标右键,可以看到一个git bash,可以很方便的打开。
image.png添加远程版本库地址 - git remote add
之后我们要给本地版本库添加远程服务器地址,这里的远程版本库地址你要改成刚刚自己复制的地址
$ git remote add origin git@github.com:Acring/git-test.git
一般没有输出就代表关联成功了,解释一下:
remote add
, 表示添加远程服务器, origin
是一个标记,也可以用你喜欢的,习惯性使用origin表示主远程服务器,因为一个项目可能有多个远程版本库。这句话就表示添加一个以origin
命名的远程版本库, 版本库地址为git@github.com:Acring/git-test.git
好了,现在本地已经知道远程版本库的地址了,我们可以把本地项目推送到远程版本库了,推送也就是上传本地版本库中的所有文件,注意是版本库,并不是工作区。
推送 - git push
推送需要用到git push,推送之前要确保所有的修改都被commit提交了,防止遗漏。
$ git push origin master
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 489 bytes | 0 bytes/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To github.com:Acring/git-test.git
* [new branch] master -> master
git push 命令后面需要两个参数,一个是远程版本库的地址,我们之前已经设定了origin远程版本库的地址,所以这里用origin
,接着是要提交的本地的分支名称,上面文章我提到了当创建版本库的时候我们默认是在master分支,所以这里写master
分支的概念先不用懂。知道我们默认处于master分支就行了。
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.
这个警告只会出现一次,后面的操作就不会有任何警告了。
接下来我们要演示的是当两个计算机协同工作时可能出现的情况以及如何去解决。
克隆远程项目 - git clone
回到Github上刚刚我们的项目网页, 刷新,我们发现git-test.md文件以及被推送上来了,那要是我们想从另一台计算机上获取下来呢,这时候就要用到我们的git clone
命令了.
首先我们还是需要远程版本库的地址,可以用上面我们复制好的,也可以在项目主页的Clone or download
中找到远程版本库地址。其实和之前的是一样的。
换一个路径来假装是另一台计算机,比如我现在切换到了D:\CODE\github
路径下。在当前目录重新打开git bash。执行克隆命令
$ git clone git@github.com:Acring/git-test.git
Cloning into 'git-test'...
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 6 (delta 0), reused 6 (delta 0), pack-reused 0
Receiving objects: 100% (6/6), done.
克隆下来之后会发现多了一个git-test文件夹,里面有我们的git-test.md文件。克隆成功!
github上的开源项目是谁的可以克隆的,你也可以用这个命令来克隆别人的开源项目。
B电脑修改并推送
这次我们对刚刚克隆下来的项目进行修改并重新推动到远程版本库, 假装新的路径属于电脑B
我们把git-test.md中的hello world
改成, hello acring
,并保存。
之后add
,commit
, 二连提交本次修改。
$ git add git-test.md
$ git commit -m "修改为hello acring"
[master 66c6021] 修改为hello acring
1 file changed, 1 insertion(+), 1 deletion(-)
然后我们再执行git push origin master
将本地的修改推送到远程版本库,这里要注意,现在clone到的是我们已经在github上提交过公钥的电脑,所以能直接push提交,如果是另一台电脑的话需要再将那台电脑的公钥提交给github,否则github是不会给你随便提push的。
A电脑修改并推送
$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 280 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:Acring/git-test.git
a26ff1d..66c6021 master -> master
提交完成之后在原本地版本库也修改一下, 把hello world
改成 hello zzq
,同样保存,add
,commit
,
再push上去,在push之前思考一下,**两台电脑都会hello world这一行做了修改,B电脑已经提交上去了,这时候A电脑要是提交上去会怎么样呢,那到底用A电脑的hello zzq
呢,还是B电脑的hello acring
呢。
这样一看似乎会乱套,我们先不管,先试着提交。
$ git push origin master
To github.com:Acring/git-test.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:Acring/git-test.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
rejected!提交被拒绝了,因为git发现B电脑修改了项目并提交了,而A电脑也修改了项目企图提交,那就会发生项目很多不一致问题,比如上面说的hello world
的选择问题。
先拉取再提交 - git pull
为了解决可能的冲突问题,A电脑需要先将远程版本库的项目拉取下来进行整合,整合完成之后再提交,这次我们不是克隆整个项目,而是在本地版本库的基础上更新远程版本库的内容。
$ git pull origin master
From github.com:Acring/git-test
* branch master -> FETCH_HEAD
Auto-merging git-test.md
CONFLICT (content): Merge conflict in git-test.md
Automatic merge failed; fix conflicts and then commit the result.
这里有一个很重要的单词,merge,合并,当拉取远程版本库的项目时,git会首先去自动合并同一个被修改的文件。
比如这里的git-test.md,假如B电脑修改的不是hello world
而是第一行学习git
,那两者对同一个文件的修改其实是不冲突的,git会同时选择AB电脑的修改,比如假设B修改的是学习git
-->不学习git
合并后的git-test.md就变成了
不学习git
hello zzq
当然现在的情况显然没有那么乐观,回头看看提示
Automatic merge failed; fix conflicts and then commit the result.
自动合并失败,请修复冲突(conflicts)并提交最终的修改结果。
是的,git处理不了两个电脑对hello world
的修改,叫我们自己来做定夺了。
打开git-test.md
image.png如果用的是Typora请点击下面的标签切换到源文本格式,否则Typora会把界面渲染的很奇怪: )
<<<<<<< HEAD
hello zzq
=======
hello acring
>>>>>>> 66c602160211831315b0a6f8eb17f3cc9cf49cf1
主要关注这几行,======
上面是A电脑的修改,下面是B电脑的修改,折中一下,我们修改成下面这样那些奇怪的箭头什么的都删掉吧。
hello zzq&acring
修改完成别忘了add
,commit
二连。
$ git add git-test.md
Acring@DESKTOP-UBU88S4 MINGW64 /d/Document/git-test (master|MERGING)
$ git commit -m "merge hello world"
[master 9fe6b47] merge hello world
好了,接着再push
$ git push origin master
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 530 bytes | 0 bytes/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To github.com:Acring/git-test.git
66c6021..9fe6b47 master -> master
这次就没什么问题了。以下是整个过程的流程图,可以重新梳理以下整个过程,并加深对各个命令的理解。
image.png
网友评论