Git
Git是什么?
Git是目前世界上最先进的分布式版本控制系统(没有之一)。
诞生
……
Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!
……
参考
https://www.liaoxuefeng.com/wiki/896043488029600
在Ubuntu上安装Git
首先,你可以试着输入git,看看系统有没有安装Git
$ git
Theprogram 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
$ sudo apt-get install git
创建版本库
什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
第一步,创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录:
$ sudo mkdir -p /var/www/git
第二步,通过git init命令把这个目录初始化为Git的仓库:
$ cd /var/www/git
$ sudo git init
Initialized empty Git repository in /var/www/git/.git/
Git建立好了一个空的仓库。
把文件添加到版本库
首先这里再明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如:TXT文件,网页,所有的程序代码等等,Git也不例外。
版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。
但图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。
不幸的是,Microsoft的Word格式是二进制格式,因此,版本控制系统是没法跟踪Word文件的改动的,前面我们举的例子只是为了演示,如果要真正使用版本控制系统,就要以纯文本方式编写文件。
因为文本是有编码的,比如中文有常用的GBK编码,日文有Shift_JIS编码,如果没有历史遗留问题,强烈建议使用标准的UTF-8编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持。
言归正传,现在我们编写一个readme.txt文件,一定要放到learngit目录下(子目录也行),内容如下:
$ cd /var/www/git
$ sudo vi x.txt
Git is aversion control system.
Git is free software.
第一步,用命令git add告诉Git,把文件添加到仓库中的暂存区(stage)
$ sudo git add x.txt
第二步,用命令git commit告诉Git,把文件提交到仓库(master):
$ sudo git commit -m "wrote a x file"
*** Please tell me who you are.
Run
git config --global user.email "[email protected]"
git config --global user.name "Your Name"
to set your account's default identity.
Omit --global to set the identity only in this repository.
fatal: unable to auto-detect email address (got 'root@hunter.(none)')
$ sudo git commit -m "wrote a x file"
[master (root-commit) a2d5804] wrote a x file
1 file changed, 2 insertions(+)
create mode 100644 x.txt
On branch master
nothing to commit, working tree clean
简单解释一下git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
git commit命令执行成功后会告诉你,
1 file changed:1个文件被改动(我们新添加的x.txt文件);
2 insertions:插入了两行内容(x.txt有两行内容)。
为什么Git添加文件需要add,commit一共两步呢?因为commit可以一次提交很多文件,所以你可以多次add不同的文件,比如:
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."
时光穿梭机
我们已经成功地添加并提交了一个x.txt文件,现在,是时候继续工作了,于是,我们继续修改x.txt文件,改成如下内容:
Git is adistributed version control system.
Git is free software.
运行git status命令看看结果:
$ git status
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: x.txt
no changes added to commit (use "git add" and/or "git commit -a")
上面的命令输出告诉我们,x.txt被修改过了,但还没有准备提交的修改。
虽然Git告诉我们x.txt被修改了,用git diff这个命令查看哪里被修改了:
Git is adistributed version control system.
$ git diff x.txt
diff --git a/x.txt b/x.txt
index 71e87b0..96c4da4 100644
--- a/x.txt
+++ b/x.txt
@@ -1,2 +1,2 @@
-Git is aversion control system.
+Git is adistributed version control system.
Git is free software.
提交修改后的文件
$ sudo git add x.txt
$ sudo git commit -m "distributed"
[master eb73f77] distributed
1 file changed, 1 insertion(+), 1 deletion(-)
日志
$ git log
commitde7a75c11e737925ddd25008c774d5d7d06c7be5
Author:LearnGit
Date: Wed Jul 3 23:06:25 2019 +0800
distributed
commit ca91d6c09c7eede5f5c09dcdc2cedef87bfea5bf
Author:LearnGit
Date: Wed Jul 3 22:50:13 2019 +0800
distributed
commitc1cf56d4d7fa4aca0440ea9cc43621d2c7456443
Author:LearnGit
Date: Wed Jul 3 22:20:27 2019 +0800
wrote areadme file
日志加参数
$ git log--pretty=oneline
eb73f777542fed5803e340de0106ff86ba617290 (HEAD -> master) distributed
1afa098e10b436ddda7f48da3ed63776ea1141ef distributed
8691734ccb275193eb03a3c58ba5f7ed706653a1 wrote a readme file
返回上一个版本
$ git reset --hard HEAD^
HEAD is now at ca91d6c distributed
Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交1094adb...(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写成HEAD~100。
跳到某个版本
$ git reset --hard
de7a75
HEAD isnow at de7a75c distributed
Git的history
$ git reflog
激活虚拟主机。
【远程仓库】
到目前为止,我们已经掌握了如何在Git仓库里对一个文件进行时光穿梭,你再也不用担心文件备份或者丢失的问题了。
可是有用过集中式版本控制系统SVN的童鞋会站出来说,这些功能在SVN里早就有了,没看出Git有什么特别的地方。
没错,如果只是在一个仓库里管理文件历史,Git和SVN真没啥区别。为了保证你现在所学的Git物超所值,将来绝对不会后悔,同时为了打击已经不幸学了SVN的童鞋,本章开始介绍Git的杀手级功能之一(注意是之一,也就是后面还有之二,之三……):远程仓库。
Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。怎么分布呢?最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的,并没有主次之分。
你肯定会想,至少需要两台机器才能玩远程库不是?但是我只有一台电脑,怎么玩?
其实一台电脑上也是可以克隆多个版本库的,只要不在同一个目录下。不过,现实生活中是不会有人这么傻的在一台电脑上搞几个远程库玩,因为一台电脑上搞几个远程库完全没有意义,而且硬盘挂了会导致所有库都挂掉,所以我也不告诉你在一台电脑上怎么克隆多个仓库。
实际情况往往是这样,找一台电脑充当服务器的角色,每天24小时开机,其他每个人都从这个“服务器”仓库克隆一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。
完全可以自己搭建一台运行Git的服务器,不过现阶段,为了学Git先搭个服务器绝对是小题大作。好在这个世界上有个叫GitHub的神奇的网站,从名字就可以看出,这个网站就是提供Git仓库托管服务的,所以,只要注册一个GitHub账号,就可以免费获得Git远程仓库。
在继续阅读后续内容前,请自行注册GitHub账号。
由于你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要一点设置:
第1步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:
$ ssh-keygen -t rsa -C "[email protected]"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/~/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/~/.ssh/id_rsa.
Your public key has been saved in /home/~/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:*
你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个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文件的内容
【添加远程库】
现在的情景是,你已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举多得。
首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库:
目前,在GitHub上的这个BenBen仓库还是空的,GitHub告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。
usage: git remote add [
] -f, --fetch fetch the remote branches
--tags import all tags and associated objects when fetching
or do not fetch any tag at all (--no-tags)
-t, --track branch(es) to track
-m, --master
master branch
--mirror[=]
set up remote as a mirror to push to or fetch from
现在,我们根据GitHub的提示,在本地的BenBen仓库下运行命令:
$ sudo git remote add origin [email protected]:qu6zhi/x.git
请千万注意,把上面的qu6zhi替换成你自己的GitHub账户名,否则,你在本地关联的就是我的远程库,关联没有问题,但是你以后推送是推不上去的,因为你的SSH Key公钥不在我的账户列表中。
添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。
下一步,就可以把本地库的所有内容推送到远程库上:
$ sudo git push -u origin master
把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。