git

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分支关联起来,在以后的推送或者拉取时就可以简化命令。

你可能感兴趣的:(git)