1. Git简介

Git是目前世界上最先进的分布式版本控制系统

1.1 什么是版本控制系统?

我们从一个例子入手来理解版本控制系统,我最近在写一篇论文,每做一个更改(删除某一段),我都要保存成一个格外的版本,例如"GAR-V1", "GAR-V2", "GAR-V3",但是等过一段时候之后,我就经常忘记我到底做了什么修改,给我的科研进度造成了不少的困扰..

于是我想,如果有一个软件,不但能自动帮我记录每次文件的改动,还可以让同事协作编辑,这样就不用自己管理一堆类似的文件了,也不需要把文件传来传去。如果想查看某次改动,只需要在软件里瞄一眼就可以,岂不是很方便?

版本 文件名 用户 用户 用户
1 GAR.doc 张三 删除了Introduction最后一段 2018.12.2 13:32
2 GAR.doc 张三 增加了Literature Review的第一句话 2018.12.6 10:21
3 GAR.doc 李四 调整了Table1 的数据 2018.12.13 17:21

1.2. Git的历史

Linux诞生(1991)->Linux手动收集开源代码(2002)->BitKeeper版本控制系统托管Linux(2002-2005)->Andrew试图破解BitKeeper被发现,BitKeeper收回免费托管权(2005)->Linux自己写了Git,也就是Git的诞生(2005)

1.3. 什么是分布式?什么是集中式?

集中式:

集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。

集中式的缺点

集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟

分布式:

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

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

分布式优点

  • 安全性高: 每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了
  • 免费

2. Git安装

先从Git官网下载安装程序,然后默认安装就可以了

安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功!

安装完成后,还需要最后一步设置,在命令行输入:

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

3. 创建一个版本库

什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录,通过git init命令把这个目录变成Git可以管理的仓库

$ git init
Initialized empty Git repository in D:/git_test/.git/

瞬间Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),细心的读者可以发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。


4. Git的语法教程


4.1. 提交一个文件到版本库

先在刚刚创建好的repository下(D:/git_test)创建一个readme.txt文件,内容如下:

Git is a version control system.
Git is free software.

提交新添加的文件到仓库只需要两步:添加(add) + 提交(commit)

第一步: 用命令git add filename.txt告诉Git,把文件添加到repository:

$ git add readme.txt

第二步: 用命令git commit -m "description" 告诉Git,把文件提交到仓库

$ git commit -m "write to readme"
[master (root-commit) f7f8050] write to readme
1 file changed, 2 insertions(+)
create mode 100644 readme.txt

git commit命令执行成功后会告诉你,1 file changed 1个文件被改动(我们新添加的readme.txt文件);2 insertions:插入了两行内容(readme.txt有两行内容)。

为什么Git添加文件需要add和commit两步?

因为commit可以一次提交很多文件,所以你可以多次add不同的文件

$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."

4.2.修改文件内容并提交

现在我们修改一下readme.txt文件内容为:

Git is a version control system.
Git is wonderful.
Git is free software.

现在我们可以通过git status来查看结果:

$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) modified: readme.txt no changes added to commit (use "git add" and/or "git commit -a")

git status命令可以让我们时刻掌握仓库当前的状态,上面的命令输出告诉我们,readme.txt被修改过了,但还没有准备提交的修改。

查看具体修改内容: 使用命令git diff

$ git diff readme.txt
diff --git a/readme.txt b/readme.txt
index d8036c1..6e4b78e 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,3 @@
-Git is a version control system.
+Git is wonderful.
-Git is free software.
\ No newline at end of file

上面显示我们新添加了一行文字

确定仓库状态和更改内容后,即可提交

第一步: add

$ git add readme.txt

查看repository状态:

$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage) modified: readme.txt

上面告诉我们,将要提交的修改包括readme.txt

第二步:commit

$ git commit -m "add new line"
[master 4fb84da] add new line
1 file changed, 1 insertion(+)

查看repository状态:

$ git status
On branch master
nothing to commit, working tree clean

4.3. 版本回退

(1) 回退前先多提交几个版本

我们先重复修改几次文本并提交

Git is a version control system.
Git is wonderful.
GitHub my lover.

然后提交:

$ git commit -m "delete software"
[master 1094adb] delete software
1 file changed, 1 insertion(+), 1 deletion(-)

现在让我们来想一下到底有几个版本被提交到仓库中了:

但是我们在实际工作中,无法记住这么多版本,我们可以通过命令git log来查看历史记录

$ git log
commit 5103166639e21fa3c8884f890ec53c0c4541f6d4 (HEAD -> master)
Author: haoch <haochen273@gmail.com>
Date: Thu Jan 3 13:19:54 2019 +0900 delete software commit 9fbb43595b5aee1773fdd2db42427d9af9275db0
Author: haoch <haochen273@gmail.com>
Date: Thu Jan 3 13:19:28 2019 +0900 github infor commit 4fb84da7882c74cc6dbd0b22ee64d8cf366e6a64
Author: haoch <haochen273@gmail.com>
Date: Thu Jan 3 13:15:00 2019 +0900 add new line commit f7f80507a255a347a92117ff3bb75ddca837b91a
Author: haoch <haochen273@gmail.com>
Date: Thu Jan 3 12:25:06 2019 +0900 write to readme

我们也可以通过另外一个命令来简化历史记录的显示git log --pretty=oneline

$ git log --pretty=oneline
5103166639e21fa3c8884f890ec53c0c4541f6d4 (HEAD -> master) delete software
9fbb43595b5aee1773fdd2db42427d9af9275db0 github infor
4fb84da7882c74cc6dbd0b22ee64d8cf366e6a64 add new line
f7f80507a255a347a92117ff3bb75ddca837b91a write to readme

(2). 版本回退到历史版本

现在-》过去

在Git中,HEAD表示当前版本, 'HEAD^'表示上一个版本, 'HEAD^^'表示上上一个版本, HEAD~10表示第前10个版本

现在,我们需要把当前版本delete software 回退到 github infor

$ git reset --hard HEAD^
HEAD is now at 9fbb435 github infor

我们在来看看历史记录git log

$ git log
commit 9fbb43595b5aee1773fdd2db42427d9af9275db0 (HEAD -> master)
Author: haoch <haochen273@gmail.com>
Date: Thu Jan 3 13:19:28 2019 +0900 github infor commit 4fb84da7882c74cc6dbd0b22ee64d8cf366e6a64
Author: haoch <haochen273@gmail.com>
Date: Thu Jan 3 13:15:00 2019 +0900 add new line commit f7f80507a255a347a92117ff3bb75ddca837b91a
Author: haoch <haochen273@gmail.com>
Date: Thu Jan 3 12:25:06 2019 +0900 write to readme

过去-》现在

其中已经没有了版本号delete software,好比你从21世纪坐时光穿梭机来到了19世纪,想再回去已经回不去了,肿么办?

办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个delete software的commit id是510316...,于是就可以指定回到未来的某个版本:

$ git reset --hard 510316
HEAD is now at 5103166 delete software

当你把电脑也关了,第二天起来想回到delete software版本怎么办?可以使用git reflog来查看每个提交的commit id在用以上的方法即可

$ git reflog
5103166 (HEAD -> master) HEAD@{0}: reset: moving to 510316
9fbb435 HEAD@{1}: reset: moving to HEAD^
5103166 (HEAD -> master) HEAD@{2}: commit: delete software
9fbb435 HEAD@{3}: commit: github infor
4fb84da HEAD@{4}: commit: add new line
f7f8050 HEAD@{5}: commit (initial): write to readme

HEAD的作用

相当于C语言中的指针一样

4.4. 工作区和暂存区

(1)工作区

就是你在电脑里能看到的目录, 例如我的git_test文件夹

(2)版本库(repository)

工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:

  • git add把文件添加进去,实际上就是把文件修改添加到暂存区;
  • git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。

(3)实例演示

让我们通过一个例子来演示工作区和版本库的作用

先对readme.txt进行一些更改为加一段文字I come from China:

Git is a version control system.
Git is wonderful.
GitHub my lover.
I come from China

然后在工作区新增一个名字为license.txt文件,内容随意

git status查看状态

$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) modified: readme.txt Untracked files:
(use "git add <file>..." to include in what will be committed) license.txt no changes added to commit (use "git add" and/or "git commit -a")

上面告诉我们:readme.txt被修改了,但是licese.txt因为没有被添加,所以是无法跟踪的untracked

我们通过add将两个文件都添加后再查看状态:

$ git add readme.txt license.txt
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage) new file: license.txt
modified: readme.txt

现在暂存区的状态就变成这样了:

git add就是把所有的修改都放到暂存区中,然后执行一次git commit就可以一次性把暂存区的所有修改提交到分支

$ git commit -m "how it works"
[master 45700b2] how it works
2 files changed, 3 insertions(+), 1 deletion(-)
create mode 100644 license.txt

一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:

$ git status
On branch master
nothing to commit, working tree clean

现在暂存区就是这样的:

4.5. 管理修改

修改readme.txt内容为添加一行:

I love China

通过git add添加

再次修改修改readme.txt内容为添加一行:

Do you like China?

再通过git commit提交,在查看状态

$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) modified: readme.txt no changes added to commit (use "git add" and/or "git commit -a")

让我们来回顾一下:

第一次修改 -> git add -> 第二次修改 -> git commit

Git管理的是修改,当你用git add命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。

提交后,用git diff HEAD -- readme.txt命令可以查看工作区和版本库里面最新版本的区别:

$ git diff HEAD -- readme.txt
diff --git a/readme.txt b/readme.txt
index 812e617..d5258f9 100644
--- a/readme.txt
+++ b/readme.txt
@@ -2,4 +2,5 @@ Git is a version control system.
Git is wonderful.
GitHub my lover.
I come from China
-I love China
\ No newline at end of file
+I love China
+Do you love china?
\ No newline at end of file

第二次修改确实没有被提交。

如何提交第二次修改

第一次修改 -> git add -> 第二次修改 ->git add -> git commit

4.6. 撤销修改

比如说你的文件里面加了一段不好的话,你想删除他的方法:

Git is a version control system.
Git is wonderful.
GitHub my lover.
I come from China
I love China
Do you love china?
My stupid techer

此时,你可以使用以下命令来丢弃工作区的修改:

$ git checkout -- readme.txt

命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

  • 一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

  • 一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

总之,就是让这个文件回到最近一次git commitgit add时的状态。

1)情况1:未添加到暂存区

现在再来看readme.txt的内容:

Git is a version control system.
Git is wonderful.
GitHub my lover.
I come from China
I love China

2)情况2:添加到暂存区

加入你在commit之前发现了这个问题,可以用以下命令撤销暂存区的修改

git reset HEAD <file>

就是把暂存区的修改退回到工作区

然后在工作区中使用情况1中的命令来删除修改

$ git checkout -- readme.txt

再次查看时候,已经回到了原来的版本了

Git is a version control system.
Git is wonderful.
GitHub my lover.
I come from China
I love China

4.7. 文件删除和恢复

Git是管理修改的,删除也是一种修改,也可以被管理

在工作区新建一个文件 text.txt并且添加提交

$ git add text.txt

$ git commit -m "add text.txt"
[master b84166e] add text.txt
1 file changed, 1 insertion(+)
create mode 100644 text.txt

一般情况下,你通常直接在文件管理器中直接把文件删除了

$ rm text.txt

Git知道你删除了文件,因此,工作区和版本库就不一致了,git status命令会立刻告诉你哪些文件被删除了:

$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) deleted: text.txt no changes added to commit (use "git add" and/or "git commit -a")

1)情况1:真的要删除文件:git rm-> git commit

$ git rm text.txt
rm 'text.txt' $ git commit -m "remove text.txt"
[master 1f108b4] remove text.txt
1 file changed, 1 deletion(-)
delete mode 100644 text.txt

2)情况2:你删错了,想恢复这个文件:git checkout -- text.txt

git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

Git&GitHub-基础教程的更多相关文章

  1. git学习基础教程

    分享一个git学习基础教程 http://pan.baidu.com/s/1o6ugkGE 具体在网盘里面的内容..需要的学习可以直接下.

  2. git github 使用教程

    参考文章:文章地址: http://wuyuans.com/2012/05/github-simple-tutorial/ github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般 ...

  3. github 基础教程推荐

    github现在很火的样子 我在一篇博客上看到说“如果你不知道什么是github,那你就不能说你是个coder,如果你现在看到这篇博客,那么你已经是个coder了”. 我对github一直很好奇,可是 ...

  4. Git入门基础教程

    目录 一.Git的安装 1.1 图形化界面 1.2 命令行界面 二.本地仓库的创建与提交 2.1 图形化界面 2.1.1 首先在电脑上有一个空白目录 2.1.2 打开SourceTree 2.1.3 ...

  5. Git入门基础教程和SourceTree应用

    目录 一.Git的安装 1.1 图形化界面 1.2 命令行界面 二.本地仓库的创建与提交 2.1 图形化界面 2.1.1 首先在电脑上有一个空白目录 2.1.2 打开SourceTree 2.1.3 ...

  6. Git & Github 使用教程【1】入门篇

    Github教程 1-1 版本管理工具简介 主要作用:备份文件.记录历史.回到过去.多端共享.独挡一面.团队协作 2-1 版本管理工具发展历史 3-1 Git下载和安装[略] 3-2 linux下安装 ...

  7. Idea+Git+GitHub图文教程,一篇教程帮你搞定

    导语 该文章主要记录如何在GitHub上创建远程仓库.如何创建本地仓库并把代码提交到GitHub.如何创建分支以及分支合并到主干的操作. 一.在GitHub上创建远程仓库 (前提:已经注册过githu ...

  8. Git和Github简单教程

    原文链接:Git和Github简单教程 网络上关于Git和GitHub的教程不少,但是这些教程有的命令太少不够用,有的命令太多,使得初期学习的时候需要额外花不少时间在一些当前用不到的命令上. 这篇文章 ...

  9. Git基础教程(二)

    继续上篇Git基础教程(一),在开篇之前,先回顾一下上篇中的基本命令. 配置命令:git config --global * 版本库初始化:git init 向版本库添加文件:git add * 提交 ...

  10. Git和Github简单教程(收藏)

    原文链接:Git和Github简单教程 目录: 零.Git是什么 一.Git的主要功能:版本控制 二.概览 三.Git for Windows软件安装 四.本地Git的使用 五.Github与Git的 ...

随机推荐

  1. OJ:析构函数实现多态

    Description 下面程序的输出结果是: destructor B destructor A 请完整写出 class A. 限制条件:不得为 class A 编写构造函数. #include & ...

  2. LeetCode-63. 不同路径 II

    最近英文版的访问特别慢,转战中文吧 和上一题一样,递归会超时 //63 不同路径2,递归解法 int uniquePaths2(vector<vector<int>>& ...

  3. 响应者链UIResponder-扩大UIButton的点击范围

    在开发中,我们经常看到有按钮等的点击,会出现响应事件.按钮->view->ViewController->UIWindow->UIApplication,这就形成了一个响应链. ...

  4. Notepad++ 配置 Sql PoorMan 插件

    作用:用来格式化 sql 命令语句 配置方法:  Notepad++ 与 PoorMan 插件要版本一致 64对64 32对32 Notepad++ 在 D:\Notepad++\plugins 目录 ...

  5. c# dllimport 调用函数,参数乱码

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalA ...

  6. [日常] MySQL数据库持久连接

    2018年5月18日 记录: 数据库持久连接: 1.持久的数据库连接是指在脚本结束运行时不关闭的连接.当收到一个持久连接的请求时.PHP 将检查是否已经存在一个(前面已经开启的)相同的持久连接.如果存 ...

  7. JavaScript 基础(三) - Date对象,RegExp对象,Math对象,Window 对象,History 对象,Location 对象,DOM 节点

    Date对象 创建Date对象 //方法1:不指定参数 var date_obj = new Date(); alert(date_obj.toLocaleString()) //方法2:参数为日期字 ...

  8. iOS----------SVN问题 the operation could not be completed

    可能是服务器磁盘满了或者你本地的内存满了

  9. 关于苹果延迟了App接入HTTPS服务截止日期

    可参考 http://www.cocoachina.com/apple/20161223/18431.html https://developer.apple.com/news/?id=1221201 ...

  10. Android 直接修改dex破解

    直接修改dex破解 一.编写一个简单的验证程序 (1)MainActivity: protected void onCreate(BundlesavedInstanceState) { super.o ...