首页 > 技术文章 > GIT前世今生

xh_chiang 2017-05-28 12:40 原文

GIT

GIT到底是什么

Git是一款免费、开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。

命名的由来(仅供参考)

The name "git" was given by Linus Torvalds when he wrote the very
first version. He described the tool as "the stupid content tracker"
and the name as (depending on your way):

链接:https://www.zhihu.com/question/54939657/answer/141820365

GIT和SVN比较

  GIT是分布式的,SVN不是。

这是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别。

  集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的的话, 日了狗了。

 

  分布式版本控制系统,根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。

 

和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。

 

在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。

  全局版本号、全球版本号。

  SVN的全局版本号和CVS的每个文件都独立维护一套版本号相比,是一个非常大的进步。

  Git的版本号则更进一步,版本号是全球唯一的。Git 对于每一次提交,通过对文件的内容或目录的结构计算出一个SHA-1 哈希值,得到一个40位的十六进制字符串,Git将此字符串作为版本号。

GIT功能特性

分布式相比于集中式的最大区别在于开发者可以提交到本地,每个开发者通过克隆(git clone),在本地机器上拷贝一个完整的Git仓库。

下图是经典的git开发过程。

 

从一般开发者的角度来看,git有以下功能:

  1. 从服务器上克隆完整的Git仓库(包括代码和版本信息)到单机上。
  2. 在自己的机器上根据不同的开发目的,创建分支,修改代码。
  3. 在单机上自己创建的分支上提交代码。
  4. 在单机上合并分支。
  5. 把服务器上最新版的代码fetch下来,然后跟自己的主分支合并。
  6. 生成补丁(patch),把补丁发送给主开发者。
  7. 看主开发者的反馈,如果主开发者发现两个一般开发者之间有冲突(他们之间可以合作解决的冲突),就会要求他们先解决冲突,然后再由其中一个人提交。如果主开发者可以自己解决,或者没有冲突,就通过。
  8. 一般开发者之间解决冲突的方法,开发者之间可以使用pull 命令解决冲突,解决完冲突之后再向主开发者提交补丁。

从主开发者的角度(假设主开发者不用开发代码)看,git有以下功能:

  1. 查看邮件或者通过其它方式查看一般开发者的提交状态。
  2. 打上补丁,解决冲突(可以自己解决,也可以要求开发者之间解决以后再重新提交,如果是开源项目,还要决定哪些补丁有用,哪些不用)。
  3. 向公共服务器提交结果,然后通知所有开发人员。

GIT优缺点

优点

适合分布式开发,强调个体。

公共服务器压力和数据量都不会太大。

速度快、灵活。

离线工作。

缺点

资料少(起码中文资料很少)。

代码保密性差,一旦开发者把整个库克隆下来就可以完全公开所有代码和版本信息

安装配置

  • 配置用户名密码

    git config --global user.name "userName"

    git config --global user.email "userEmail"

    git config --global --list

  • 生成、配置公匙

    ssh-keygen -t rsa -C "something"

可以生成两个文件,这两个文件的命名默认是 id_rsa 和 id_rsa.pub,如果你在键入上述命令回车之后,重新输入了命名,那此时生成的两个文件就是 [命名] 和 [命名].pub

id_rsa 可以称之为私有密钥,id_rsa.pub 可以称之为公有密钥。我们会把公有密钥交给服务端,当需要从服务端请求内容的时候,要带上私有密钥。此时,服务器会通过一定的算法计算私有密钥,并判断计算的结果是否与公有密钥一样,如果不一样则响应请求失败。

+-----------+                           +-----------+
|           |                           |           |
|           |    enc(rsa) == rsa.pub    |           |
|  client   | ------------------------> |   server  |
|           |             ?             |           |
|           |                           |           |
+-----------+                           +-----------+

 rsa.pub 里面是个什么东西,其实很简单:

 ssh-rsa base64(加密内容) "something"

 而 rsa 中是:

 -----BEGIN RSA PRIVATE KEY-----
 base64(私有密钥的一些处理)
 -----END RSA PRIVATE KEY-----

  • 中文文件名和路径乱码

解决这个问题,只需要告诉 git 不对 0x80 以上的字符进行转义即可:

git config --global core.quotepath false

基础命令

专用名词的译名如下:

l  Workspace:工作区

l  Index / Stage:暂存区

l  Repository:仓库区(或本地仓库)

l  Remote:远程仓库

clear

清屏

git status

git status

git status –s

git diff

git diff  # 此命令比较的是工作目录和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。

git diff --cached [file]  # 查看已经暂存起来的文件(staged)和上次提交时的快照之间(HEAD)的差异

git diff HEAD  # 显示工作区和HEAD的差别

git diff [first-branch]...[second-branch]  # 显示两次提交之间的差异

git clean

git clean -fx 删除所有未被版本控制的文件

git clean -fd 删除所有未被版本控制的目录及文件

git add

git add .

git add filename

git stash

git stash  # 暂时将未提交的变化移除

git stash pop  # 稍后再移入

git commit

git commit -m "描述信息"

git reset

git reset –mixed    # 此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本,只保留源码,回退commit和index信息

git reset –soft     # 回退到某个版本,只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可

git reset –hard    # 彻底回退到某个版本,本地的源码也会变为上一个版本的内容

git reset HEAD        # 撤销git add添加的所有文件

git reset HEAD XXX/XXX/XXX.java    # 撤销git add添加的某一个文件

git branch

git branch branchName

git branch –r

git branch –d branchName

git branch –D branchName

git checkout

git checkout .  # 恢复暂存区的所有文件到工作区

git checkout [file]  # 恢复暂存区的指定文件到工作区

git checkout -  # 切换到上一个分支

git checkout branchName  # 切换到新分支

git checkout -b branchName  # 创建并切换到新分支

git push

git push  <远程主机名>  <本地分支名>  <远程分支名>

git push origin master:master  # 将本地的master分支推送到远程主机origin上的对应master分支, origin 是远程主机名

git push origin master  # 如果远程分支被省略,如上则表示将本地分支推送到与之存在追踪关系的远程分支(通常两者同名),如果该远程分支不存在,则会被新建

git push origin :master  # 删除远程master分支

git push origin  # 如果当前分支与远程分支存在追踪关系,则本地分支和远程分支都可以省略,将当前分支推送到origin主机的对应分支

git push  # 如果当前分支只有一个远程分支,那么主机名都可以省略,形如 git push,可以使用git branch -r ,查看远程的分支名

git remote

git remote –v

git merge

git merge branchName

git fetch

git fetch  # 相当于是从远程获取最新版本到本地,不会自动merge

git fetch orgin master  # 将远程仓库的master分支下载到本地当前branch中

git fetch origin master:temp  # 从远程仓库master分支获取最新,在本地建立temp分支

git pull

git pull  # 相当于是从远程获取最新版本并merge到本地,等同于git fetch + git merge

git pull origin master   # 从远程获取最新版本并merge到本地

进阶命令

删除不存在对应远程分支的本地分支

git fetch -p  #删除不存在对应远程分支的本地分支

重命名远程分支

git push --delete origin devel  #删除远程分支

git branch -m devel develop  #重命名本地分支

git push origin develop  #推送本地分支

用户名密码

       git config --global credential.helper wincred          # 缓存

  git credential-manager uninstall          # 删除缓存

解决冲突

  1. git pull
  2. Beyond Compare工具比对修改
<<<<<<< HEAD
b789
=======
b45678910
>>>>>>> 6853e5ff961e684d3a6c02d4d06183b5ff330dcc

冲突标记<<<<<<<与=======之间的内容是我的修改,=======与>>>>>>>之间的内容是别人的修改。

参考资料

官网:https://git-scm.com/

TortoiseGit无限弹密码框的解决办法: https://jingyan.baidu.com/article/4d58d54165b8f79dd5e9c046.html

推荐阅读