git 使用简明手册

 
 
git 是由Linus Torvalds领衔开发的一款开源、分布式版本管理系统,显然,git最初是为了帮助管理Linux内核开发而开发的版本控制系统。
版本控制系统本身并不要求一个中央服务器(远端仓库)来存储所有数据,虽然svn是这样做的。
Git允许克隆仓库,克隆的仓库跟被克隆的仓库的数据和功能完全一样,中央服务器的概念只是使用上的一种习惯;
每个仓库都可以和其它仓库交换文件,从而实现仓库数据的同步。

代码在workspace、本地仓库、远端仓库之间的数据同步流程图如下:

从上面的流程图可以看出,本地git仓库(Repository)是由三棵“树”组成:

1、工作目录(working space),它持有实际文件;

2、暂存区(Index/Stage),它像个缓存区域,临时保存你的改动;

3、当前版本(HEAD),HEAD^ 指上一版本,HEAD^^ 指上上一个版本,HEAD~100往上100个版本。

开发人员在working space中对文件做的修改,需要先add到index,然后再提交到HEAD(即Repository)。
PS:如果在add之后,commint之前又修改了文件,这些修改不会自动保存到index,需要再次执行add命令;
 

可见,working space与本地仓库Repository之间的代码流动,跟SVN的workspace和服务器中央仓库之间的流动类似,通过checkout、add、commit命令控制。

与SVN不一样的是,git是分布式的,不存在一个托管所有代码的“中央服务器”。

或者从某种意义上来说,git有很多“中央服务器”,这些“中央服务器”可以是本地仓库,也可以是远端仓库,仓库之间也可以进行代码同步。

一、git 常见的应用场景

代码提交(Merge Request)流程

  • git checkout -b ${branch_name},创建并切换分支
  • git checkout ${branch_name},只切换分支
  • git add ${file_name},将工作目录中修改过的文件添加到暂存区(working space -> Index)
  • git commit -m "${msg}",将暂存区的文件提交到本地仓库(Index -> HEAD)
  • git remote add origin ${server},关联到远程仓库(这是先有本地仓库,后有远程仓库的情况,反之就用git clone命令将远程仓库复制到本地)
  • git push origin ${branch_name},将本地某个分支的修改推送到远端服务器(远程仓库已存在)

撤销修改(未提交到版本库)

  • git checkout -- ${file_name},丢弃在working space的修改;
  • git reset HEAD ${file_name},撤销已经保存到index(但没有commit)的修改,修改会回滚到working space中;
  • git reset --hard origin/${branch_name},用远程仓库的文件覆盖本地的修改(包括working space和Index);
 

版本回退(已提交到版本库)

  • git reset --hard HEAD^,回退到上一个版本;
  • git reset --hard ${commit_id},滚动到指定版本;

更新本地仓库

  • git pull,将远程仓库的修改拉取到本地仓库;
  • git merge ${branch_name},将指定分支合并到当前分支;
  • git fetch origin,

二、git 分支管理

git 会把每次提交串成一条时间线,这条时间线就是一个分支,例如下面的master分支:

每次提交,master就向前一步,master指向最近一次提交,而HEAD指向master,所以HEAD就指向了当前分支的提交点。

当创建一个分支dev时,Git新建一个指针dev,指向与master相同的提交点,再把HEAD指向dev,就表示当前分支在dev上。

如上图,可见Git创建一个分支很快,因为除了增加一个dev指针,再修改HEAD的指向,working space的文件都没有任何变化!

不过,从现在开始,对working space的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:

假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

所以Git合并分支也很快!就改改指针,working space内容也不变!

上面这种merge方式是快进模式(Fast-forward ),直接把master指向dev的当前提交,所以合并速度非常快。但这种模式下,删除分支后,会丢掉分支信息。当然,也不是每次合并都能Fast-forward,我们后面会讲其他方式的合并。

合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

Git鼓励大量使用分支:

  • 查看分支:git branch,-a 列出所有分支, -r 远程分支;
  • 创建分支:git branch ${branch_name}
  • 切换分支:git checkout ${branch_name}
  • 创建并切换分支:git checkout -b ${branch_name}
  • 合并某分支到当前分支:git merge ${branch_name},--no-ff 选项可以关闭Fast-forward合并模式;
  • 删除分支:git branch -d ${branch_name},如果分支还未合并到主分支会报错;
  • 强制删除:git branch -D ${branch_name},丢弃一个没有被合并过的分支,删除后无法恢复;

冲突

考虑一种更复杂的情况,master分支和dev分支各自都有新的提交,变成了这样:

此时git merge命令可能会产生冲突(如果修改了通过一个文件),

此时可以用git status查看冲突文件,并手动修改冲突文件然后保存,再利用git add和git commit命令提交。

上面这种merge方式不能用Fast-forward模式,而是像这样:

stash

有时候我们需要在当前开发分支(dev)中,停下来去处理bug,而当前dev分支没有完成,又不能提交到master,这个时候可以使用stash功能。

  • git stash, 保存现场(包括working space和Index)到stash;
  • git stash pop,恢复现场,并把stash内容也删除;
  • git stash list,查看stash内容;
  • git stash apply,只恢复现场,不删除stash内容;
  • git stash drop,删除stash内容;

三、Git命令

创建新仓库(init)

创建新文件夹,打开,然后执行

git init

以创建新的 git 仓库。

克隆仓库(clone)

执行如下命令以创建一个本地仓库的克隆版本:

git clone /path/to/repository 

如果是远端服务器上的仓库,你的命令会是这个样子:

git clone username@host:/path/to/repository

该命令会在本地主机生成一个目录,与远程主机的版本库同名。如果要指定不同的目录名,可以将目录名作为git clone命令的第二个参数:

git clone <版本库的网址> <本地目录名>

另外,git clone支持多种协议,除了HTTP(s)以外,还支持SSH、Git、本地文件协议等,下面是一些例子:

git clone http[s]://example.com/path/to/repo.git/
git clone ssh://example.com/path/to/repo.git/
git clone git://example.com/path/to/repo.git/
git clone /opt/git/project.git
git clone file:///opt/git/project.git
git clone ftp[s]://example.com/path/to/repo.git/
git clone rsync://example.com/path/to/repo.git/

远程仓库(remote)

列出所有的远程主机名:

git remote 

加上选项-v可以查看远程主机的地址

对远程主机的操作:

git remote show <主机名>
git remote add <主机名> <网址>
git remote rm <主机名>
git remote rename <原主机名> <新主机名>

查看(diff/status/log)

查看版本修改的历史日志

git log --pretty=oneline

git的版本号与SVN的纯数字不一样,它是一个SHA1计算出来的一个非常大的数字,用十六进制表示。

查看working space的具体修改

git diff
git diff filename

查看working space的修改状态

git status

推送改动(push)

你的改动现在已经在本地仓库的 HEAD 中了。执行如下命令以将这些改动提交到远端仓库:

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

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

分支(checkout)

分支是用来将特性开发绝缘开来的。在你创建仓库的时候,master 是“默认的”分支。在其他分支上进行开发,完成后再将它们合并到主分支上。

创建一个叫做“feature_x”的分支,并切换过去:

git checkout -b feature_x

切换回主分支:

git checkout master

除非你将分支推送到远端仓库,不然该分支就是不为他人所见的:

git push origin <branch>

在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。

比如,在git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动"追踪"origin/master分支。

Git也允许手动建立追踪关系:

git branch --set-upstream master origin/next

上面命令指定master分支追踪origin/next分支。

获取分支(fetch)

fetch命令可以将远端主机的更新取回本地:

git fetch <远程主机名> <分支名>

若省略<分支名>,则更新远程主机的全部分支。

所取回的更新,在本地主机上要用"远程主机名/分支名"的形式读取,比如origin主机的next分支,就要用origin/next读取。

取回远程主机的更新以后,可以在它的基础上,使用git checkout命令创建一个新的分支

git checkout -b newBrach origin/next

此外,也可以使用git merge命令或者git rebase命令,在本地分支上合并远程分支

git merge origin/next
或者
git rebase origin/next

更新与合并(pull)

取回远程主机某个分支的更新,再与本地的指定分支合并:

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

如果本地分支名是当前分支,本地分支名可以省略不写;

如果当前分支与远程分支存在追踪关系,git pull就可以省略远程分支名。

git pull origin

上面命令表示,本地的当前分支自动与对应的origin主机"追踪分支"(remote-tracking branch)进行合并。

如果当前分支只有一个追踪分支,连远程主机名都可以省略:

git pull

上面命令表示,当前分支自动与唯一一个追踪分支进行合并。

例如,取回远程主机origin的next分支,与本地的master分支合并,可以执行:

git pull origin next:master

这等同于先做git fetch,再做git merge:

git fetch origin next
git merge origin/next

在这两种情况下,git 都会尝试去自动合并改动。遗憾的是,这可能并非每次都成功,并可能出现冲突(conflicts)。 这时候就需要你修改这些文件来手动合并这些冲突(conflicts)。改完之后,你需要执行如下命令以将它们标记为合并成功:

git add <filename>

在合并改动之前,你可以使用如下命令预览差异:

git diff <source_branch> <target_branch>

标签(tag)

TAG就是指向某个commit的指针。你可以执行如下命令创建一个叫做 1.0.0 的标签:

git tag 1.0.0  1b2e1d63ff

1b2e1d63ff 是你想要标记的提交 ID 的前 10 位字符。可以使用下列命令获取提交 ID:

git log

你也可以使用少一点的提交 ID 前几位,只要它的指向具有唯一性。

如果不写commit ID,则默认取最近的提交(即默认HEAD)。

tag的作用主要是比commit id更方便记忆 。

git tag -d ${tag_name}, 删除本地标签
git push origin :refs/tags/${tag_name},删除远程仓库的标签
git push origin ${tag_name},将指定标签push到远程仓库
git push origin --tags,将所有标签push到远程仓库

替换本地改动

假如你操作失误(当然,这最好永远不要发生),你可以使用如下命令替换掉本地改动:

git checkout -- <filename>

此命令会使用 HEAD 中的最新内容替换掉你的工作目录中的文件。已添加到暂存区的改动以及新文件都不会受到影响。

假如你想丢弃你在本地的所有改动与提交,可以到服务器上获取最新的版本历史,并将你本地主分支指向它:

git fetch origin
git reset --hard origin/master

git 简明使用手册的更多相关文章

  1. Git 简明手册

    0,Git 是什么 Git 是一个VCS(Version Control System),即版本控制系统. 版本控制系统从字面意思来看,它的用途就是管理/控制文件的版本.使用它,可以方便的知道一个文件 ...

  2. 【转】git - 简明指南

    git - 简明指南 助你入门 git 的简明指南,木有高深内容 ;) 作者:罗杰·杜德勒 感谢:@tfnico, @fhd 和 Namics其他语言 english, deutsch, españo ...

  3. Markdown 简明语法手册

    Markdown 简明语法手册 本文原文http://www.jianshu.com/p/fdb5cbdaf244 根据个人使用情况有所修改. Markdown是一种轻量级标记语言,简称md.创始人为 ...

  4. 《zw版·Halcon-delphi系列原创教程》 Halcon分类函数·简明中文手册 总览

    <zw版·Halcon-delphi系列原创教程> Halcon分类函数·简明中文手册 总览 Halcon函数库非常庞大,光HALCONXLib_TLB.pas文件,源码就要7w多行,但核 ...

  5. Cmd Markdown 简明语法手册

    『Cmd 技术渲染的沙箱页面,点击此处编写自己的文档』 Cmd Markdown 简明语法手册 标签: Cmd-Markdown 1. 斜体和粗体 使用 * 和 ** 表示斜体和粗体. 示例: 这是 ...

  6. Git常用命令手册

    github 的使用教程(非常详细的小白视频)链接如下: http://yun.itheima.com/course/209.html Git 详细使用手册链接如下: https://git-scm. ...

  7. Git 安装配置手册

    Git 安装配置手册 首先我们要了解 Git 是类似于 SVN 用来管理项目的 首先要先下载 Git ,这个东西相当于一个核,是该功能的核心 下载地址(<https://gitforwindow ...

  8. Jinja2 简明使用手册

    @Jinja2 简明使用手册(转载) 介绍 Jinja是基于python的模板引擎,功能比较类似于于PHP的smarty,J2ee的Freemarker和velocity. 运行需求 Jinja2需要 ...

  9. Git Hub 使用手册参考

    参考信息 1.http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b0002.http://ww ...

随机推荐

  1. 100722A

    这道题抄了答案: 思路:旋转,其实只用旋转四次,因为在换行的过程中旋转其实是没有意义的,因为行列只不过转了个角度.然后主要的是行列的交换,这里我很头疼,写了个盲目搜索,当然wa掉了 问了问某位同志,是 ...

  2. css-画三角箭头

    .arrow { width:; height:; content: ""; border: solid 10px #7c7; display: block; border-top ...

  3. Android GUI系统

    图解Android - Android GUI 系统 (1) - 概论 图解Android - Android GUI 系统 (2) - 窗口管理系统 图解Android - Android GUI ...

  4. 解决jQuery UI 对话框兼容性问题

    默认情况下使用jQuery UI的对话框,在Chrome浏览器是没问题的,但是在IE里却会显示对话框,用户体验非常不好.改变一下div的属性即可. 原本是这样: <div id="di ...

  5. bzoj4400: tjoi2012 桥

    先传代码再填坑 #include <iostream> #include <cstdio> #include <cmath> #include <cstrin ...

  6. python第一天

    python 解释器执行代码有两种 一种在解释器: win+R==>cmd 打开终端进行 输入python 加 路径 另一种在文件里写完再到解释器执行:win+R==>cmd 打开终端进行 ...

  7. bzoj 2005

    裸的2D gcd.ans=(Σ(d<=n)phi[d]*(n/d)*(m/d))*2-n*m; #include<iostream> #include<cstdio> # ...

  8. 【BZOJ-3589】动态树 树链剖分 + 线段树 + 线段覆盖(特殊的技巧)

    3589: 动态树 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 405  Solved: 137[Submit][Status][Discuss] ...

  9. jdbc实现事务

    //conn需要自己获取,这里我用的时springjdbcTemplate Connection conn = null; PreparedStatement pstm = null; try { c ...

  10. JSR303注解

    Annotation 属于Bean Validation 规范 应用位置 作用 对Hibernate Core中的元数据的影响 @AssertFalse yes field/property 检查被标 ...