git基本命令讲解

GIT 基本特点

       1.直接快照,而非比较差异 2.近乎所有操作本地执行 3.时刻保持数据完整性 

为什么要用GIT?

      最明显特征是分布式:客户端并不只提取最新版本的文件快照,而是把原始的代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的提取操作,实际上都是一次对代码仓库的完整备份。

      创建分支快捷轻便:创建分支其实只创建一个新的分支指针即可。

GIT基本原理:三种状态、四种对象(再次赘述下)

     状态一:git repository 即 Git 目录( .git )

                 •每个项目都只有一个.git目录,为项目存储所有元数据和对象数据库。包括所有的对象(commits,trees,blobs,tags)。
                 •每次克隆镜像仓库的时候,实际拷贝的就是这个目录里面的数据。

     状态二:working copy Git 工作目录

                •Git的工作目录存储从项目中取出的某个版本的所有文件和目录。
                •当在项目的不同分支间切换时,工作目录里的文件经常会被替换和删除。所有历史信息都保存在GIT目录(.git)中;

     状态三:staging area Git 暂存区域

                •所谓的暂存区域只不过是一个简单的文件,一般都放在 Git 目录中。也可以叫做index索引文件。

    四种对象:

                •blob--文件内容
                •tree -- 所有文件或目录名字及其属性的列表
                •commit--表示一个版本,根据此对象内的tree或blob对象可以求索某个时刻整个版本仓库状态。
                •tag–标签,它可以指向blob,tree,commit,大部分是commit

用户环境设置:

        git config [–global | --system ]  (–system 参数修改/etc/gitconfig文件,针对所有用户适用配置;–global 参数修改~/.gitconfig文件,针对该用户适用配置)

初始化仓库:

       git init   (创建一个空的git仓库或初始化一个已存在仓库,会建立一个隐藏.git目录)

获取代码库:

       git clone [url]  (默认把远程仓库整个clone下来,但只会在本地创建master分支;如果远程还有其他分支,git branch -a查看所有分支;git支持ssh、git、http/s、本地协议,一般用ssh协议)

添加目录下修改、或新增加的文件到仓库暂存区:

       git add -A | -u | -f | filename   (-A表示添加所有文件;-u添加所有跟踪文件;-f 强制添加被忽略文件;filename添加指定文件)

删除文件:

       git rm [filename] 删除受版本控制的文件或文件夹 (-rf是删除文件夹)

移动文件:

       git mv [sourcefile] [destinationfile] 移动源文件为目标文件,相当于重命名。

忽略版本控制的文件用正则匹配添加在.gitignore:  

 eg:     $ cat .gitignore  

                   # frameworks/base   # 此为注释,被git忽略

                   *.a     # 忽略所有.a结尾的文件 

                   !lib.a     # 但lib.a除外

                   !build/     # 忽略build目录下的所有文件 

                   doc/*.txt     # 忽略doc目录下的所有.txt结尾文件,但不包含doc/notes/*.txt

                   /TODO    # 仅忽略项目根目录下的TODO文件,但不包含subdir/TODO

提交存储在当前index即暂存区的文件:

       git commit -m 'your description'  (提交后会显示本次提交的完整 SHA-1 校验和, 以及在本次提交中,有多少文件修改过,多少行添改和删改过;-a参数会兼并git add动作)注:不填提交说明不能提交

查看仓库状态:

       git status (查看仓库当前工作于哪个分支;查看文件状态:被修改,被删除,新增加等)注:每次提交前,都用git status查看下是不是都已暂存起来了,然后再提交。

       git status会提示你目前工作目录下各修改过的文件的状态:

eg:当前干净目录:

新建文件并跟踪:git status提示“new file”处于“Changes to be committed”状态,说明是已暂存状态。

修改已有文件README:git status提示“modified”文件处于“Changes not staged for commit:”状态,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。要暂存这次更新,需要运行 git add 命令

git add 已修改文件:git status 提示已暂存状态,与刚才追加跟踪文件track一样:提示“Changes to be committed:”

git commit 两个文件:提示 “nothing to commit, working tree clean”

查看提交历史:

       git log [ -5 | -p | - - author="fx" | - - since/- -until =“2017-06-06-24”| - - graph | - - pretty=format:%h:%s ]  (最近5次提交;fx的提交;-p显示所有的commit的详细的修改内容及提交信息;指定日期之后或截止指定日期的提交;图   形方式显示提交;定义格式显示)

比较差异:

       git diff :不带参数比较的是wc与staging的差异;

       git diff - -cached 比较的是stading与仓库的差异;

       git diff HEAD比较当前工作空间与本地仓库差异;

       git diff newbranch比较当前工作空间与新分支差异;

       git diff - -state统计差异文件个数;

       git diff tag1 tag2 ;

       git diff tag1:file1 tag2:file2 ;

       git diff tag1 tag2 file 

还原版本:

       git reset - -hard HEAD 回复到HEAD状态;

       git reset - -hard HEAD^ 彻底撤销最近一次提交;

       git reset - -soft HEAD~3 将最近3次提交撤掉到stage状态;

       git reset - - mixed 撤销add动作

撤销提交:

       git  revert  master~3 或git revert SHA1

修改提交:

       git commit - -amend (如果上次提交时遗漏了文件,可以在提交后将文件加入缓存然后用该命令提交即可,它会打开vi编辑器让你编辑commit message)注:只限于未push的提交

       比较git reset、git revert、git checkout、git commit

              •git reset:撤销最近的提交,此次之后的修改都会被退回到暂存区,ws不变(默认参数--mixed)

              •git revert:撤销某次提交,此次操作之前的commit都会被保留

              •git checkout - - file:将文件从stage的状态撤销,原有修改将找不到;

              •git commit - -amend:修改最后一次提交的内容及注释

GIT如何创建分支并切换到新分支,如何在不同分支间转换,合并本地分支?

GIT如何把分支推送到共享服务器上,同世界分享?如何使用共享分支与他人协作,以及在分享之前进行衍合?解读如下......

远程仓库:
       列出当前远程库:git remote -v (-v列出远程仓库地址);
       添加远程仓库:git remote add [shortname] [url] ;
       查看远程仓库信息:git remote show  [remote-name] ;
       远程仓库重命名:git remote rename [remote-name] [new-remote-name] ;
       删除远程仓库:git remote rm [remote-name]
       从远程仓库拉取数据:git fetch  [remote-name] (fetch只是拉取远程仓库你本地还没有的数据,不会自动合并到你本地分支,需要手动合并;如果设置了跟踪分支可以直接用git pull命令自带合并,创建跟踪分支见如下分支部分)
       推送数据到远程仓库:git push [remote-name] [local-branch-name]:[remote-branch-name]   注:Push成功具备条件:你在所克隆的服务器有写权限;目前origin上的数据没被其他人推送过,如果在上次拉取到本次推送有人像origin推送过,必须先更新到本地再行推送。
  
标签:
       查看标签:git tag –l ;
       新建标签:三种类型
                        轻量级标签:实际就是一个保存着对应提交对象的校验和信息的文件。  创建时不需加-a,-s,-m参数:$ git tag v2017.06_01
                        含附注标签:存储在仓库中的一个独立对象,创建时用-a(annotated)指定标签名字,-m指定对应的标签说明:$git tag –a v2017.06_02  –m  “testtag2”
                        签署标签:如果你有自己的私钥,还可以用 GPG 来签署标签(-s参数):git tag -s v1.5 -m 'my signed 1.5 tag' 
       补打标签:即对任何版本创建tag:$git tag –a v2017.06_02 –m “testtag2” 04c5624ec6218e7
       推送标签:默认情况下push不会将标签推送到远程服务器,需要带参数提醒git推送:$git push origin v2016.06_02
分支: 
       创建分支:git branch testing
       切换分支:git checkout  testing  (创建并切换:git checkout -b testing;$ git checkout –b testing master   # 基于master分支创建并切换到testing分支) 
       查看分支:git branch   -v | - -merged | - - no-merged  (-v显示各个分支最后一次commit信息;后两个参数显示已经(或尚未)与当前分支合并的分支)
       删除分支:git branch -d testing 
       获取远程分支:git fetch origion/branchname 
       合并远程分支:git merge origin/branchname
       创建跟踪分支:git branch branchname origin/remote_branchename ;创建远程分支的本地跟踪分支并切换上去:git checkout -b  track_branchname origin/remote_branchename
       删除远程分支:git push origin :branchname 注:对比git push [远程名] [本地分支]:[远程分支] 语法,如果省略 [本地分支],那就等于是在说“在这里提取空白然后把它变成[远程分支]”。
分支合并:merge、rebase、cherry-pick
举例:

       test,master分支各有一次提交  共同祖先:C2 

1、采用merge三方合并方式合并test分支的修改到master分支上:

      $ git checkout master

      $ git merge test

冲突解决:

      任何包含未解决冲突的文件都会以未合并(unmerged)状态列出。git status --->显示unmerged状态

       vi 冲突文件,合并部分用<<<,===,>>> 分隔符标记,手动解决冲突后,删掉这些标记;

      在解决完所有文件的冲突后,执行git add ,使文件标记为冲突已解决;

      运行git status查看文件状态为modified;

      执行git commit 提交,完成这次合并提交。

2、采用rebase方式合并test分支的修改到master分支上,rebase方式官方叫衍合:分为两步完成

      衍合基础:开发进程分叉到两个不同的分支,又各自进行了提交

      衍合原理:回到两个分支的共同祖先,提取你当前分支每次提交时产生的差异(diff),把这些差异分别保存到临时文件里,然后从当前分支转换到你需要衍合入的分支,依序施用每一个差异补丁文件。
step1:
          $ git checkout test;
          $ git rebase master;  

说明:1、在test分支中,把C3里产生的差异保存到临时文件中;2、切换到master分支,将差异应用到master分支上;3、切换回test分支;

 注:修改的是test分支,master分支没有变化。

step2:将test分支 rebase master 分支后:

           $ git checkout master  #切换回master分支;

           $ git merge test  #合并test分支到master分支,进行一次快进合并

在执行git rebase时,同时修改了同一文件的某一行或几行,可能会发生冲突。 冲突发生时,工作空间处于no branch的状态。

 冲突解决:

      用vi 编辑文件,找到<<<和>>>的冲突标记,解决冲突,然后删除掉冲突标记;

      解决完冲突后,git add 文件,然后执行git rebase - - continue, 继续衍合其余的commit;

      在执行git add 后,工作空间处于你所在的分支;如果此时还是no branch状态,说明冲突没有解决彻底;

      解决冲突后,不要执行 git commit,否则会在执行git rebase  --continue时,提示仍然有冲突,但实际上已经解决完冲突了;如果执行了git commit,那么在提示错误时,执行git rebase -- skip , 忽略此次冲突提示

3、采用cherry-pick的方式将test分支的修改合并到master分支上:git cherry-pick sha1

      关于cherry-pick: cherry-pick 可应用于同一远程库不同分支的提交,也可用于不同远程库的分支,需在本地工作空间中添加远程库,fetch远程库的数据到本地库 。

      $ git checkout master  # 切换到master分支 ;

       $ git cherry-pick C3-SHA1  # 合并test分支的C3提交到master分支 ;

       $ git branch –d test   # 合并完成后,可以删除test分支 

原文地址:https://www.cnblogs.com/junlinqunxia/p/7085251.html