Git

 什么是Git? 

  Git是一个分布式代码管理工具。

    中央式代码管理:所有的代码保存在中央服务器,所以提交必须依赖网络,并且每次提交都会带入到中央仓库,如果是协同开发可能频繁触发代码合并,进而增加提交的成本和代价。最典型的就是SVN

    分布式代码管理:可以在本地提交,不需要依赖网络,并且会将每次提交自动备份到本地。每个开发者都可以把远程仓库clone一份到本地,并会把提交历史一并拿过来。代表就是Git

  Git相比与SVN的优势在于代码回退,因为commit的成本比较小,并且本地会保存所有的提交记录,随时随刻可以进行回退。

 一、基本概念

  1、文件状态 

    在Git中文件大致分为:已修改(modified)、已暂存(staged)、已提交(committed)

    已修改:Git可以感知到工作目录中哪些文件被修改了,然后把修改的文件加入到modified区域

    已暂存:通过add命令将工作目录中修改的文件提交到暂存区,等候被commit

    已提交:将暂存区文件commit至Git目录中永久保存

  2、Commit节点

    在Git中每次提交都会生成一个节点(节点即commit提交),而每个节点都会有一个哈希值(SHA1)作为唯一标示,多次提交会形成一个线性节点链(不考虑merge的情况)。

    后面的节点包含前面节点的提交内容

  3、HEAD

    HEAD可以理解为指针或引用,它可以指向任意一个节点,并且指向的节点始终为当前工作目录,换句话说就是当前工作目录(也就是你所看到的代码)就是HEAD指向的节点

    同时HEAD也可以指向一个分支,间接指向分支所指向的节点

  4、远程仓库

    虽然Git会把代码以及历史保存在本地,但最终还是要提交到服务器上的远程仓库。

    通过clone命令可以把远程仓库的代码下载到本地,同时也会将提交历史、分支、HEAD等状态一并同步到本地,但这些状态并不会实时更新,需要手动从远程仓库去拉取

  5、分支

    当一个分支指向一个节点时,当前节点的内容即是该分支的内容。

    分支的概念和HEAD非常接近同样也可以视为指针或引用,不同的是分支可以存在多个,而HEAD只有一个。

    通常会根据功能或版本建立不同的分支

    注意:当在某个节点创建一个分支后,并不会把该节点对应的代码复制一份出来,只是将新分支指向该节点,因此可以很大程度减少空间上的开销。一定要记着不管是HEAD还是分支它们都只是引用而已,量级非常轻

 二、Git命令

  Git命令手册:http://git-scm.com/docs

  GitBook:http://git-scm.com/book/zh/v2

  1、提交相关

 命令  说明
 git add 文件路径  添加某个文件到暂存区,add之后,IDE中新增文件从红色变绿色
 git add .  添加所有文件到暂存区
 git checkout -- 文件名  撤销工作区对文件的改动,文件在本地的任何修改都会消失——Git 会用最近提交的版本覆盖掉它
 git reset HEAD 文件名  取消暂存区的该文件,对已经提交的文件不起作用
 git commit -m "代码提交信息"

 提交暂存区到本地仓库,将改动文件加入到暂存区后就可以进行提交了,提交后会生成一个新的提交节点

 这个时候,改动已经提交到了HEAD,但是还没到远程仓库中。

 git log  查看历史提交记录(不显示被删除的commit),按字母 Q 即可退出
 git blame <file>  以列表形式查看指定文件的历史修改记录,按字母 Q 即可退出
 git reflog  可以查看所有分支的所有操作记录(包括已经被删除的commit记录和reset的操作)

  推送改动:

命令 说明
git push origin master 将本地仓库的改动推送到远端仓库,可以把master替换为你想要推送的任何分支
git remote add origin <server> 如果你还没有克隆现有仓库,并欲将你的仓库连接到某个远程服务器,可使用此命令,如此就能够将改动推送到所添加的服务器上去了

  

  2、分支相关

 命令  说明
 git branch 分支名  创建分支;创建一个分支后该分支会与HEAD指向同一节点,说通俗点就是HEAD指向哪创建的新分支就指向哪
 git checkout 分支名  切换分支;当切换分支后,默认情况下HEAD会指向当前分支,即HEAD间接指向当前分支指向的节点
 git checkout -b 分支名  创建一个分支,并切换过去
 git branch -d 分支名  删除分支,当分支上开发的功能合并到主分支后,应该及时将这个分支删除

  3、合并相关

    常用的合并有merge、rebase、cherry-pick

    1)merge

      merge是最常用的合并命令,它可以将某个分支或者某个节点的代码合并至当前分支

      命令:git merge 分支名/节点哈希值

      注意:如果两个节点同时修改了同一个文件中的同一句代码,这个时候合并会出现冲突(conflicts),因为Git不知道该以哪个节点为标准,所以这个时候需要我们自己手动合并代码

      手动合并之后,需要执行 git add <filename> 将它们标记为合并成功。

      在合并改动之前,可以通过使用 git diff <source_branch> <target_branch> 预览差异

    2)rebase

      命令:git rebase 分支名/节点哈希值

    3)cherry-pick

       cherry-pick的合并不同于merge和rebase,它可以选择某几个节点进行合并

      命令:git cherry-pick 节点哈希值

  4、回退相关

    1)分离HEAD

      在默认情况下HEAD是指向分支的,但也可以将HEAD从分支上取下来直接指向某个节点,此过程就是分离HEAD。

git checkout 节点哈希值
// 也可以直接脱离分支指向当前节点
git checkout --detach

     为什么要分离HEAD?

      如果开发过程发现之前的提交有问题,此时可以将HEAD指向对应的节点,修改完毕后再提交,此时你肯定不希望再生成一个新的节点,而你只需在提交时加上--amend即可,具体命令如下:

git commit --amend

    2)回退

      git reset 命令用于回退版本,可以指定退回某一次提交的版本

      reset和相对引用很像,区别是reset会使分支和HEAD一并回退

      git reset 语法格式:

git reset   [--soft | --mixed | --hard]    [HEAD]
# --mixed 为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变。

      HEAD说明:

        HEAD 表示当前版本

        HEAD^ 上一个版本

        HEAD^^ 上上一个版本

        HEAD^^^ 上上上一个版本

       也可使用~数字表示:

        HEAD~0 表示当前版本

        HEAD~1 上一个版本

        HEAD^2 上上一个版本

        HEAD^3 上上上一个版本

        依此类推...

$ git reset HEAD^            # 回退所有内容到上一个版本  
$ git reset HEAD^ hello.php  # 回退 hello.php 文件的版本到上一个版本  
$ git reset 052e           # 回退到指定版本

       --soft 参数用于回退到某个版本 

git reset --soft HEAD
# 回退上上上一个版本
git reset --soft HEAD~3

      --hard 参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一个版本,并删除之前的所有信息提交

      注意:请谨慎使用 –hard 参数,它会删除回退点之前的所有信息

git reset --hard HEAD

# 回退上上上一个版本
git reset –hard HEAD~3
# 回退到某个版本回退点之前的所有信息
git reset –hard bae128
# 将本地的状态回退到和远程的一样
git reset --hard origin/master

      

  5、远程相关

    1)clone

      在Git中可以通过clone从远程仓库复制一份代码到本地:

git clone 仓库地址

      clone不仅仅是复制代码,它还会把远程仓库的引用(分支/HEAD)一并取下保存在本地

    2)fetch

      fetch命令就是一次下载操作,它会将远程新增加的节点以及引用(分支/HEAD)的状态下载到本地

git fetch 远程仓库地址/分支名

    3)pull

      pull命令可以从远程仓库的某个引用拉取代码:

git pull 远程分支名

      其实pull的本质就是fetch+merge,首先更新远程仓库所有状态到本地,随后再进行合并。合并完成后本地分支会指向最新节点

      另外pull命令也可以通过rebase进行合并:

git pull --rebase 远程分支名

    4)push

      push命令可以将本地提交推送至远程: 

git push 远程分支名

      如果直接push可能会失败,因为可能存在冲突,所以在push之前往往会先pull一下,如果存在冲突本地解决。push成功后本地的远程分支引用会更新,与本地分支指向同一节点

   6、仓库相关

    初始化一个仓库

      ①:使用当前目录作为Git仓库,我们只需要将它初始化:git init

      ②:指定目录作为Git仓库:git init 目录名

    初始化后,会在指定的仓库目录下生成一个名为 .git的目录,所有Git需要的数据和资源都存放在这个目录中。

    如果当前目录下有几个文件想要纳入版本控制,需要先用git add 命令告诉Git开始对这些文件进行跟踪,然后提交:  

# 将当前目录下修改的所有代码从工作区添加到暂存区 . 代表当前目录
git add .
# 将目录下所有以 .c 结尾的文件添加到暂存区
git add *.c
# 添加一个或多个文件到暂存区
git add [file1] [file2] ...
# 添加指定目录到暂存区,包括子目录
git add [dir]

# 将暂存区文件提交
git commit -m '初始化项目版本'

# 查看项目的当前状态
git status 

     查看远程仓库:git remote

      也可以指定选项-v,会显示需要读写仓库使用的Git保存的简写及其对应的URL。

    

    

    

   7、命令大全

  推送项目代码到Git

  

    

 三、Git

   工作流

    你的本地仓库由git维护的三棵"树" 组成。

    1、你的工作目录,它持有实际文件

    2、暂存区(stage 或 Index),它像个缓存区域,临时保存你的改动。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)

    3、HEAD,它指向你最后一次提交的结果,HEAD保存在工作区的隐藏目录.git,也就是版本库中

     

    暂存区(Staging Area,或 Index):

      这是一个中间区域,可以在完成提交之前格式化和审查提交。

      所以Git可以快速暂存一些文件并提交它们,而无需提交工作目录中的所有其他修改过的文件,也不必在提交期间在命令行中列出它们。

    

      git commit -a 即可将所有文件的所有更改添加到暂存区

      

   

       commit提交时,Git用暂存区域的文件创建一个新的提交,并把此时的节点设为父节点。然后把当前分支HEAD指向新的提交节点。

       

    checkout

      checkout命令用于从历史提交(或暂存区域)中拷贝文件到工作目录,也可用于切换分支。

      

  Gi图形化工具:https://www.sourcetreeapp.com/

END.

原文地址:https://www.cnblogs.com/yangyongjie/p/15746904.html