Git学习笔记
之前曾经快速学习过一次廖雪峰老师的Git教程,但是由于是速学且没有记笔记,到现在要使用已经基本完全忘记了,所以重新学习一次且记下笔记,方便以后Git命令的查询。
Git常用命令
这里列出的常用命令是下面各个章节的总结部分,所以有不明白怎么用的命令,只需要找到对应章节观看即可。
- 使用命令
git init
初始化一个仓库。 - 添加文件到仓库,分两步:
- 使用命令
git add <file>
添加文件到暂存区。 - 使用命令
git commit -m <message>
提交文件到仓库。
- 使用命令
- 修改仓库中的文件:
- 使用命令
git status
随时掌握工作区的状态。 - 使用命令
git diff <file>
可以查看更改内容。
- 使用命令
- 版本回退牵涉到的命令如下:
- 使用命令
git reset --hard <commit_id>
在历史版本之间穿梭。HEAD
指向的版本就是当前版本。 - 使用命令
git log
可以查看提交的历史版本,以便确定要回退到哪个版本。 - 使用命令
git reflog
查看命令历史,以便确定要去到未来的哪个版本。
- 使用命令
- 丢弃修改:
- 场景1:当你改乱了工作区的某个文件内容,想直接丢弃工作区的修改,使用命令
git checkout -- <file>
。 - 场景2:当你改乱了工作区的某个文件内容,并且还
add
到了暂存区,先使用命令git reset HEAD <file>
回到场景1,再按场景1的操作丢弃修改。 - 场景3:当你改乱了工作区的某个文件内容,不仅
add
而且还commit
了,参考上一章“版本回退”,前提是没有推送到远程库。
- 场景1:当你改乱了工作区的某个文件内容,想直接丢弃工作区的修改,使用命令
- 删除文件:
- 使用命令
git rm <file>
从版本库删除一个已经在工作区被删除的文件,然后需要commit
。 - 使用命令
git checkout -- <file>
从版本库恢复一个已经在工作区被误删的文件。
- 使用命令
- 关联一个空的远程库:
- 使用命令
git remote add origin git@server-name:path/repo-name.git
关联一个远程库; - 使用命令
git push -u origin master
第一次推送master
分支的所有内容。 - 使用命令
git push origin master
推送之后的提交。
- 使用命令
- 从远程库克隆:
- 使用命令
git clone <SSH key>
克隆远程仓库。
- 使用命令
- 关联一个空的远程库:
- 使用命令
git remote add origin git@server-name:path/repo-name.git
关联一个远程库; - 使用命令
git push -u origin master
第一次推送master
分支的所有内容。 - 使用命令
git push origin master
推送之后的提交。
- 使用命令
- 从远程库克隆:
- 使用命令
git clone <SSH key>
克隆远程仓库。
- 使用命令
Git历史
Git是目前世界上最先进的分布式版本控制系统。与分布式版本系统对应的是集中式版本控制系统。
- Linus在1991年创建开源的Linux社区,手工管理全世界志愿者发给他的代码。
- 2002年,BitMover公司授权Linux社区免费使用商业版本控制系统BitKeeper。
- 2005年,一些开发者(例如开发Samba的Andrew)试图破解BitKeeper的协议,于是BitMover公司收回Linux社区的免费使用权。这时,Linus可以选择向BitMover公司道歉且保障约束手下。但是大佬怎么可能道歉???So,Linus花两周时间用C语言写了一个分布式版本控制系统,就是Git。
- 2008年,GitHub上线。
安装Git
过于简单,不再废话。
创建仓库
仓库又称版本库(repository)。目前可以先简单理解为一个目录,目录中的所有文件都可以被Git管理起来,后文会有专门的章节细讲。
创建版本库的过程:
- 创建一个空目录(也可以使用非空的目录):
mkdir testgit
- 进入这个目录,然后将这个目录初始化为Git的仓库testgit:
cd testgit
git init
然后可以发现这个目录下多了一个.git
目录。
总结:
使用命令git init
初始化一个仓库。
添加文件到仓库
假设我们已经在仓库目录下创建编辑保存新文件(例如创建test.txt文件),之后需要将其添加并提交到仓库。
- 将文件添加到暂存区:
git add test.txt
这个命令执行后没有任何显示。
Unix的哲学:“没有消息就是好消息”。
暂存区的概念后文会详解。
2. 把文件提交到仓库:
git commit -m "write test.txt file"
每次commit
都是一个新的版本。-m
选项后是本次提交的说明(即版本说明),方便以后在查阅历史记录时知道此次提交的改动。可以没有,但建议有。
3. 可以一次add
多个文件,也可以多次add
后一次commit
:
git add file1.txt
git add file2.txt file3.txt
git commit -m "add 3 files"
- 一次
add
所有的修改:
git add .
git中的修改的涵义是:新增一行,删除一行,更改了某些字符,删除一些又增加了一些,创建一个新文件,都是一个修改。
每当自己感觉文件修改到一定程度的时候,就可以“保存一个快照”,即commit
。如果误删或改乱了文件,可以从最近一个commit
恢复,然后继续工作。
总结:
添加文件到仓库,分两步:
6. 使用命令git add <file>
添加文件到暂存区。
7. 使用命令git commit -m <message>
提交文件到仓库。
修改仓库中的文件
假设我们对仓库中的文件(例如test.txt)已经作出更改并保存,之后要做的事情如下所示。
- 首先查看是否有待添加、提交的文件,包括新建的和更改过的,即查看工作区状态:
git status
由于刚刚我们更改了test.txt,执行了status
命令后可以看到更改的文件需要add
。
2. 查看我们刚刚对test.txt做了那些更改:
git diff test.txt
这个命令会把我们对test.txt做得更改全部显示出来。
3. 再次把更改过的test.txt添加到仓库:
git add test.txt
添加之后,再使用status
查看工作区状态,显示的内容会变成提示更改的文件需要commit
。如果修改并add
了多个文件,status
会显示下次commit
时所有提交的文件。
4. 再次把刚刚更改的test.txt提交到仓库:
git commit -m "some changes to test.txt"
提交之后,再使用status
查看工作区状态,显示的内容是当前没有要commit
的东西,工作目录是干净的。
总结:
修改仓库中的文件:
- 使用命令
git status
随时掌握工作区的状态。 - 使用命令
git diff <file>
可以查看更改内容。
版本回退
假如我们已经对testgit仓库做了很多次的commit
,每次commit
就是一个新版本,那么testgit就会有很多个历史版本,我们可以在这些版本之间进行切换,回到之前的版本或再重新来到新的版本。
HEAD
指针表示当前所在的版本,默认应该是最新版;HEAD^
表示上一个版本;HEAD^^
表示上上一个版本;依次类推;HEAD~100
表示往上100个版本。
- 查看历史记录
git log
这个命令会列出所有曾经commit
的版本及其说明(这里的“说明”就是-m
后的内容),下图是笔者测试log
命令得到的其中的一个版本的信息:
上图中,commit
后的信息是commit_id
即版本号。Author
后的信息是提交这个版本的作者及邮箱。Data
后的信息是这个版本提交的时间信息。最下面的内容是这个版本相对于上一版本的改动。
可以看到log
输出信息很多,可以加上--pretty=oneline
参数使输出信息精简:
git log --pretty=oneline
输出如下图:
只输出了版本号及相对于上一个版本的改动。
2. 可以在历史版本进行穿梭。改变HEAD
所指的版本,即可完成历史版本穿梭,例如,回到上一个版本的命令:
git reset --hard HEAD^
--hard
参数的意义:
如果想去到特定的某个版本,可以使用commit_id
,而且不需要写全commit_id
(太长了),只需要写前几位能唯一表示即可:
git reset --hard <commit_id>
- 如果我们使用
reset
命令回退到某一历史版本,这是再使用log
命令查看历史版本,无法在查看比这一版本更新的版本。那么再想去到较新版本需要使用新版本的commit_id
,没有关闭命令行的情况下可以从以前执行log
的信息里面找到新版本的commit_id
;如果已经关闭命令行,也可以使用reflog
查看执行过的命令,找到之前commit
较新版本的历史命令记录,有commit_id
:
git reflog
总结:
版本回退牵涉到的命令如下:
- 使用命令
git reset --hard <commit_id>
在历史版本之间穿梭。HEAD
指向的版本就是当前版本。 - 使用命令
git log
可以查看提交的历史版本,以便确定要回退到哪个版本。 - 使用命令
git reflog
查看命令历史,以便确定要去到未来的哪个版本。
工作区和暂存区、丢弃修改
- 工作区:就是在电脑里看到的目录,例如我们的testgit目录。
- 版本库(Repository)即仓库
工作区下有一个隐藏目录.git
,这个不算工作区,而是Git的版本库。
版本库中主要有:称为stage或index的暂存区,Git自动创建的第一个分支master
,以及指向master
的一个指针HEAD
。如下图:
上文我们讲过将新建或更改过的文件添加到Git版本库分两步:- 用
add
命令把文件添加进去,实际上就是把文件的修改添加到暂存区; - 用
commit
命令提交修改,实际上就是吧暂存区的所有内容提交到当前分支。
可以简单理解为:需要提交的文件修改通通放在暂存区,然后一次性提交暂存区的所有修改到当前分支。
Git中的修改:新增一行,删除一行,更改了某些字符,删除一些又增加了一些,创建一个新文件,都是一个修改。
- 用
- 查看工作区和版本库里面最新版本的区别:
git diff HEAD -- <file>
- 丢弃还未
add
的修改:
git checkout -- <file>
分两种情况分析此条命令:
- 此文件自修改后还没有被放到暂存区,执行此命令后文件就回到和版本库一模一样的状态;
- 此文件已经添加到暂存区但没有
commit
,又做了修改,执行此命令就回到和暂存区一模一样的状态。
注意:命令中的--
很重要,如果没有--
,就变成了“切换到另一个分支”的命令。 - 丢弃已经
add
但还未commit
的修改分两步:- 先把暂存区的修改撤销掉(unstage):
git reset HEAD <file>
- 再丢弃工作区的修改,即4中的方法。
总结:
丢弃修改:
- 场景1:当你改乱了工作区的某个文件内容,想直接丢弃工作区的修改,使用命令
git checkout -- <file>
。 - 场景2:当你改乱了工作区的某个文件内容,并且还
add
到了暂存区,先使用命令git reset HEAD <file>
回到场景1,再按场景1的操作丢弃修改。 - 场景3:当你改乱了工作区的某个文件内容,不仅
add
而且还commit
了,参考上一章“版本回退”,前提是没有推送到远程库。
删除文件
假如我们使用rm
命令删除了工作区的某个文件(删除也是一种修改)。
- 查看那些文件被删除同样使用
git status
命令。 - 从版本库中删除该文件:
git rm <file>
git commit -m "some message"
- 如果删错了,可以从版本库中恢复到最新版本:
git checkout -- <file>
这种情况下此命令是用版本库的版本替换工作区的版本。
注意: 没有添加到版本库就被删除的文件,是无法恢复的。
总结:
删除文件:
- 使用命令
git rm <file>
从版本库删除一个已经在工作区被删除的文件,然后需要commit
。 - 使用命令
git checkout -- <file>
从版本库恢复一个已经在工作区被误删的文件。
远程仓库
可以使用GitHub提供的Git仓库托管服务作为远程仓库使用。
- 注册GitHub账号。由于本地Git仓库和GitHub仓库之间是通过SSH加密的,所以需要设置密钥,从而让GitHub识别出推送的提交确实是你本人,而不是其他人冒充的。Git是支持SSH协议的。下面是添加密钥的步骤。
- 在本地创建SSH Key。在用户主目录下查看是否有
.ssh
目录,如果有,再查看此目录下是否有id_rsa
和id_rsa.pub
这两个文件。如果有,转下一步 ;如果没有,在终端创建SSH Key:
ssh-keygen -t rsa -C "youremail@example.com"
然后一路回车,使用默认值即可(当然也可以自己根据提示选项设置一个密码)。
3. 登录GitHub
第一步,点击左上角的头像
第二步,选择Setting
第三步:选择SSH and GPG keys:
第四步:选择New SSH key:
第五步:在Title文本框中自己起一个名字
第六步:在Key文本框中粘贴id_rsa.pub
的内容:
第七步:选择Add SSH key
4. GitHub可以添加多个key,这样如果你有多个电脑,那么就可以使用不同的电脑往GitHub提交了。
总结:
都是在GitHub和本地进行的操作,没有Git命令,所以没什么好总结的。
添加远程库
现在我们有了Git仓库,又有了GitHub可以作为远程仓库,那么我们如何让本地Git仓库(例如我们的testgit)和远程Github上的Git仓库远程同步呢?
- 登录GitHub,创建新的仓库
第一步:点击右上角的“+”
第二步:点击New repository
第三步:在Repository name文本框中输入仓库名字
第四步:如果选择Initialize this repository with a README,那么仓库会自动创建一个README.md文件。因为我们这里要和本地仓库同步,要创建一个空仓库,所以不勾选!
第五步:点击Create repository创建新的仓库
- 在本地的仓库下运行下面的命令添加远程仓库:
git remote add origin git@github.com:qiyinhe/testgit.git
请注意将命令中的qiyinhe更改为你自己的GitHub名。
添加后,远程库的名字就是origin
,这是Git的默认叫法,也可以改成别的。
3. 将本地库的所有内容推送到远程库上:
git push -u origin master
这条命令将本地库master
分支的内容推送到远程。关于分支的内容下面会讲解。
执行完这条命令就可以在GitHub看到远程库的内容和本地一模一样了。
由于在执行此命令前远程库是空的,并且我们是第一次推送master分支,加上了-u
参数,这会使Git将本地的master
分支和远程库的master
分支关联起来,在以后的推送push
时或拉取pull
时简化命令。
4. 第一次push
后,只要在本地做了提交commit
,就可以通过命令:
git push origin master
把本地master
分支的最新修改推送push
到GitHub。
5. 第一次使用Git的clone
和push
命令连接GitHub时,会得到一个SSH警告:
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)?
直接输入yes
回车即可。
总结:
关联一个空的远程库:
- 使用命令
git remote add origin git@server-name:path/repo-name.git
关联一个远程库; - 使用命令
git push -u origin master
第一次推送master
分支的所有内容。 - 使用命令
git push origin master
推送之后的提交。
从远程库克隆
- 获取远程库的SSH key
- 克隆一个本地库:
git clone git@github.com:user_name/reposity_name.git
将上面的user_name
和reposity_name
换成要克隆的GitHub用户名和远程库的名字。
3. 也可以使用http地址,但是http速度慢,而且每次推送都需要输入口令。
总结:
从远程库克隆:
- 使用命令
git clone <SSH key>
克隆远程仓库。