--- layout: post title: 开源分布式管理控制系统——Git笔记 description: 开源分布式管理控制系统——Git笔记 category: tech thumb: 'IMG_PATH/git.jpg' tags: [git, 分布式,管理控制系统] --- ## Git的诞生  故事是自2002年开始,[林纳斯·托瓦兹][1]决定使用[BitKeeper][2]作为[Linux内核][3]版本控制系统,用于维护代码。你想想BitKeeper是[专有软件][4],人家靠这玩意挣钱,这个决定社群中长期遭受质疑。不过还是有人主张使用开源软件。我dalao(林纳斯·托瓦兹)何尝没有想过(如[Monotone][5]),但是这些软件都存在一些问题,特别是性能不佳。现成的方案,如[CVS][6]的架构,不过dalao并不喜欢连同痛批了一顿。  2005年的时候有个叫[安德鲁·垂鸠][7]破解了BitKeeper(这么做的不止他一个),BitMover公司决定收回Linux社区的免费使用权。事后双方公司进行过磋商,结果可想而知。事后dalao以十天的时间,用C撸出来一个分布式版本控制系统,它就是Git的第一个版本!于2005年以[GPL][8]发布。至于这个名字嘛,dalao自嘲地取了这个名字“**Git**”,该词源自英国俚语,意思大约是“混账”。不过Git刚面世的时候,世界上开源社群反对声音不少,最大的理由是Git太艰涩难懂?(博主:一个程序员难道不该有钻研精神吗?)  2016年IT界报道,Git统治编程社区11年后,BitKeeper宣布开源。挑战Linux内核开发者?dalao反手一掏Git灭掉BitMover。(这段让我看的热血沸腾,抽颗烟压压惊) 在学习之前我门先学习一下四个专业术语 ![Alt text]({{ site.IMG_PATH }}/flow%20chart.jpg "Git数据流程图") * **Workspace**:工作区 * **lndex/Stage**:暂存区(又名索引) * **Repository**:仓库区(又名本地仓库、储存库) * **Remote**:远程仓库 开源分布式管理控制系统——Git笔记 开源分布式管理控制系统——Git笔记是工作区。 开源分布式管理控制系统——Git笔记态。 开源分布式管理控制系统——Git笔记库)。 远程仓库:这个很简单但我却不知道怎么表达...可以说成云端仓库吧。 ## 主要功能  Git主要用于Linux内核开发的版本控制系统,与[CVS][6]或[Subversion][9]这一类集中式版本控制系统的不同采用了分布式版本。它没有服务器端,就可以运行版本控制,这使得源码的发布与修改极其方便。git速度也是很给力。 ## 实现原理  Git和其他版本控制系统(如[CVS][6])有不少的差别,Git本身关心文件的整体性是否有改变,但多数的版本控制系统如[CVS][6]或[Subversion][9]系统则在乎文件内容的差异。 我觉得Git更像一个文件系统,直接在本机上获取数据,不必连线到主机端获取数据。 每个开发者都可有全部开发历史的本地副本,changes从这种本地repository复制给其他开发者。这些changes作为新增的分支被导入,可以与本地分支合并。 Git是用C语言开发的,以追求最高的性能。Git自动完成[垃圾回收][10](也可以用 git gc --prune 调用)。 Git服务器典型的TCP监听,端口为9418。 ## Git的安装  Git平台支持有[POSIX][11]、[Windows][12]、[OS X][13],不过今天我们重点讲Linux。 Git安装有许多种,主要分为两种:通过编译源代码、平台预编译安装包,源代码安装至少可以安装最新版本,不过Git慢慢壮大,不会出现安装包版本落后问题,这里也就不说了。   在装软件之前我都会习惯的更新源 ```bash $ sudo apt-get update ``` 基于二进制安装Git ```bash $ sudo yum install git ``` ubuntu发行版 ```bash $ sudo apt-get install git ``` 查看Git当前版本 ```bash $ git version ``` ## 初始化仓库 ```bash # 初始化当前目录为仓库 $ git init ``` ## 克隆到本地仓库 ```bash # 第二个参数克隆到指定目录,可带可不带 $ git clone [项目链接] [指定本地目录] # 帮助 $ git clone -h ``` ## 增加/删除文件 ```bash # 提交新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件 $ git add . # 提交新文件(new)和已被删除(deleted)文件,不包括新文件 $ git add -u # 提交所有变化。cunz $ git add -A # 提交当前目录.png后缀文件 $ git add *png # 帮助 $ git add -h ``` ## 检查工作目录/暂存区状态 ```bash # 检查工作目录与暂存区的状态 $ git status # 只列出已被Git管理且被修改没提交的文件 $ git status -uno # 帮助 $ git status -h ``` ## 获得远程仓库权限 ```bash # Git是分布式管理控制系统,基于SSH,所以我们要生成SSH公钥,然后它让输入的话就 Enter $ ssh-keygen # 之后切换到主目录下的 ~/.ssh 并找到 .pub 且复制文件内容(Windows在:C:/Users/当前用户名/.ssh/id_rsa.pub) $ cd ~/.ssh && ls authorized_keys id_rsa id_rsa.pub known_hosts # 在Github页面 找到 Settigs -> SSH and GPG keys ->New SSH key 然后给这个秘钥取个名字,然后把Key填入并保存 # 当新文件添加到暂存区后,我们现在就准备创建第一个提交与注释了,不过在这之前我们要绑定Git账户,之后进行push操作需要填写账号\密码 $ git config --global user.email "achuan@achuan.io" $ git config --global user.name "achuanya" ``` ## 提交代码并注释 ```bash $ git commit -m "这是一个测试" # 参数: # 自动检测修改文件 -a # # 提交 -m # 帮助。 $ git commit -h ``` ## 查看日志详情 ```bash # 显示当前分支的版本历史 $ git log # 显示commit历史,以及每次commit发生变化的文件 $ git log --stat # 搜索提交历史,根据关键词 $ git log -S [key Word] # 显示某个文件的版本历史,包括文件改名 $ git log --follow [file] # 显示过去的5次提交 $ git log -5 --pretty --oneline # 帮助 $ git log -h ``` ## 提交到远程仓库 ```bash # 提交到远程仓库,master即为分支 $ git push origin master # 强行提交 $ git push -u origin master # 上传本地指定分支到远程仓库(分支操作后面会说到) $ git push [remote] [branch] # 推送所有分支到远程仓库 $ git push [remote] --all # 强行推送当前指定分支到远程仓库(即使有冲突) $ git push [remote] --force # 帮助 $ git push -h ``` ## 移动、重命名与删除文件 ```bash # 移动与重命名道理是一样的 $ git mv # 继linux命令一样。 $ git rm ``` ![Alt text]({{ site.IMG_PATH }}/rename.png?achuan.io "重命名操作") ## 撤销修改/切换分支  git checkout 主要用于撤销修改或切换分支,它是一条较为常用的的命令,同时也很危险,因为这条命令会重新工作区! ```bash # 恢复修改过的指定文件到工作区 $ git checkout [branch Name] # 恢复暂存区所有文件到工作区 $ git checkout . # 新建一个分支,并切换到该分支(切换分支不带参数 -b) $ git checkout -b [name] # 切换到上一个分支 $ git checkout - ``` ## 管理分支  Git分支,好比一包零食,你可以选择和其他小伙伴一起吃一包,也可以自己吃一包,他们吃他们的,你吃你的相互之间没有影响,作为这包零食的主人,你也可以随时可以让两包零食放在一起(合并)。 ​ ```bash # 现在让我们创建一包零食,不不不...一个新分支 $ git branch [name] # 查看本地所有分支(当前分支前有个 * 号) $ git branch # 查看远程分支 $ git branch -r # 查看本地和远程所有分支 $ git branch -a # 重命名分支 $ git branch -m [name] [modify Name] # 删除分支( -D 强行删除) $ git branch -d [name] 注:删除远程分支需要 git push 操作 $ git push origin :[name] ######################### 合并分支 # 把现有demo分支合并到master上 $ git metge [branch Name] root@achuan-pc:/home/github/demo# git branch demo * master root@achuan-pc:/home/github/demo# git merge demo Updating d46f35e..b17d20e Fast-forward README.txt | 1 + 1 file changed, 1 insertion(+) # 注意上面的合并信息 fasht-forward 意思是这次合并是快进模式,也就是直接吧master指向demo的当前提交,所以合并速度非常快。 ``` ## Git常用命令  上面说的都是一些基本操作,下面也是一些常用命令,出于个人用途可能存在有些命令不全面,不过我往后学习中会进行添加,还请见谅。 ### 查看信息 ```bash # 显示所有提交过的用户,按提交次数排序 $ git shortlog -sn # 显示指定文件是什么人在什么时间修改过 $ git blame [file] # 显示暂存区和工作区的差异 $ git diff # 显示暂存区和上一个commit的差异 $ git diff --cached [file] # 显示工作区与当前分支最新commit之间的差异 $ git diff HEAD # 显示两次提交之间的差异 $ git diff [first Branch]...[second Branch] # 显示今天你写了多少行代码 $ git diff --shortstat "@{0 day ago}" # 显示某次提交的元数据和内容变化 $ git show [commit] # 显示某次提交发生变化的文件 $ git show --name-only [commit] # 显示某次提交时,某个文件的内容 $ git show [commit]:[filename] # 显示当前分支的最近几次提交 $ git reflog ``` ### 远程仓库的一些操作 ```bash # 下载远程仓库的所有变动 $ git fetch [remore Name] # 跟踪存储库,不带参数,列出已存在的远程分支。 $ git remote # 显示所有远程仓库 $ git remote -v # 显示某个远程仓库的信息 $ gitremote shou [remote Name] # 添加一个新的远程仓库,并命名 $ git remote add [shortname][url] # 取远程仓库与本地分支合并 $ git pull [remote] [branch] ``` ## 拓展知识 ### 克隆下载某项目中的单个文件(文件夹) ```bash $ wget https://github.com/acversionuanya/achuanya.github.io/blob/master/README.mdjinxing ``` ### Github Chrome插件 [Octotree][14],很直观的查看不同级文件夹,也方便进行文件跳转操作。 [Octo Mate][15],增强你Githubt体验,它主要功能有四点:一键以.zip格式下载文件、 一键打开项目的Github Pages、显示仓库大小、显示未读消息数。 ### 文件状态 ```bash 未跟踪(untrack):新增加文件。 已修改(modified):已修改但为写入到暂存区。 已暂存(staged):已经添加到暂存区。 已提交(committed):已经添加到远程仓库。 ``` ### Git专业术语中英文对照表 ![Alt text]({{ site.IMG_PATH }}/terminology.png "Git专业术语中英文对照表")
 ok写完了!通过这段时间的学习,关于Git命令我用到的差不多就这么多,可能存在有些命令不全面,不过我往后学习中会进行添加,还请见谅。我现在真高兴当初出写博客这个决定,它让我每天学习都很有动力,有目标。最主要的是能把自己学会的知识分享给大家,也能让这个知识点记的更加牢固。。再过半年就要入职场了,压力也是不小。不过不能让压力阻止我向前跨步!下次文章关于“LAMP/LNMP架构”的相关内容。 ### 2019-04-28 更新 ```bash # 撤销所有 git reset HEAD -- . # 撤销指定文件 git reset HEAD -- filename [文件名] # 将文件从缓存中删除 git rm -cached filepath [文件名] ``` [1]: https://zh.wikipedia.org/wiki/%E6%9E%97%E7%BA%B3%E6%96%AF%C2%B7%E6%89%98%E7%93%A6%E5%85%B9?achuan.io [2]: https://zh.wikipedia.org/wiki/BitKeeper?achuan.io [3]: https://zh.wikipedia.org/wiki/Linux%E5%86%85%E6%A0%B8?achuan.io [4]: https://zh.wikipedia.org/wiki/%E4%B8%93%E6%9C%89%E8%BD%AF%E4%BB%B6?achuan.io [5]: https://zh.wikipedia.org/wiki/Monotone?achuan.io [6]: https://zh.wikipedia.org/wiki/%E5%8D%94%E4%BD%9C%E7%89%88%E6%9C%AC%E7%B3%BB%E7%B5%B1?achuan.io [7]: https://zh.wikipedia.org/wiki/%E5%AE%89%E5%BE%B7%E9%AD%AF%C2%B7%E5%9E%82%E9%B3%A9?achuan.io [8]: https://zh.wikipedia.org/wiki/GNU%E9%80%9A%E7%94%A8%E5%85%AC%E5%85%B1%E8%AE%B8%E5%8F%AF%E8%AF%81?achuan.io [10]: https://zh.wikipedia.org/wiki/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6_(%E8%A8%88%E7%AE%97%E6%A9%9F%E7%A7%91%E5%AD%B8)?achuan.io [9]: https://zh.wikipedia.org/wiki/Subversion?achuan.io [11]: https://zh.wikipedia.org/wiki/POSIX?achuan.io [12]: https://zh.wikipedia.org/wiki/Microsoft_Windows?achuan.io [13]: https://zh.wikipedia.org/wiki/MacOS?achuan.io [14]: https://chrome.google.com/webstore/detail/octotree/bkhaagjahfmjljalopjnoealnfndnagc/related?achuan.io [15]: https://chrome.google.com/webstore/detail/octo-mate/baggcehellihkglakjnmnhpnjmkbmpkf?achuan.io