Android Studio中的Git实践

Git是一个开源、分布式的版本控制系统,与集中式版本控制系统(如SVN)最大的区别在于每个开发者都会有一个本地仓库,代码可以提交到本地,不需要依赖远程代码仓库。
git每次存的都是项目的完整快照(完整的项目代码),因此需要的硬盘空间会相对大一点(Git团队对代码做了极致的压缩 最终需要的实际空间比svn多不了太多 可是Git的回滚速度极快)。
git的每一次提交都是一个快照而不是增量,项目的版本是一个提交对象,项目的快照是一个树对象,如果想要回退版本或切换版本,只要找到提交对象的hash即可。

创建远程仓库

  • 通常一个项目需要创建一个远程代码仓库。我们可以使用GitHub、GitLab等代码托管平台,或者也可以使用GitLab、Gitblit等部署一个代码服务器。
  • 创建一个远程空仓库的时候,不要添加README、.gitignore、license,后续项目有需要再添加进来。因为本地代码一开始是不存在这些文件的,如果远程仓库不是空仓库,多出了那几个文件,本地代码将推送不上来。
  • 在Android studio中,暗红色的文件表示没有被git跟踪、黑色的文件表示被git忽略的文件、绿色的文件表示被git跟踪。
  • Git管理代码分为工作区间、暂存区和版本库三个区域,我们写代码的区域属于工作区,写完之后需要将创建的文件或修改的代码添加到暂存区(git add),然后才能提交到版本库。
  • 当我们使用了git add命令之后,之前那些暗红色的文件就会变成绿色,表示这些文件已被git跟踪,并添加进暂存区。
  • git commit命令表示将代码提交到本地仓库,git push命令表示将本地仓库中的代码推送到远程分支。提交之后,文件又变回黑色。

分支

分支由一个个提交按时间顺序串联起来,分支与分支之间就像平行线,合并两个分支才会出现交叉的情况。创建Git仓库时,默认创建的分支是主分支master分支,当我们第一次推送时,实际上是将本地master分支推送到远程代码仓库,这时远程代码仓库也有一个分支,叫origin/master。
注意:当我们创建一个分支之后,新的分支只有本地仓库才有,如果需要把该分支保存到远程代码仓库,需要执行git push命令。
同理,如果我们删除了本地master分支,远程的master分支并不会被删除;如果删除了远程master分支,本地master分支不会被删除。
在Android studio中可以通过“Local Branches”和“ Remote Branches”来区分本地分支和远程分支,该标识位于Android studio的右下方。

获取(Fetch)

Fetch就是获取当前分支对应的远程分支最新的提交记录,可以简单地理解为同步远程分支的更新。对应的命令为git fetch。

拉取(Pull)

获取当前本地分支对应的远程分支的更新,然后将这些更新合并到本地分支上,实际上就是fetch之后再merge。对应的命令为git pull。

衍合(Rebase)

在实际工作中,通常是本地master分支多了几个提交时origin/master分支没有的,而origin/master分支也有其他开发者的提交是本地master分支没有的,这种情况就不能直接push到远程仓库中,必须要先merge远程分支的提交,再推送到远程分支。或者使用衍合:将远程分支的最新的提交作为起点,再将本地分支新的提交添加到后面,衍合之后提交的记录就是一条直线。
注意:衍合尽量少用,多用合并

贮藏(Stash)

在开发中可能遇到这种情况,我们在一个分支上做开发,这时突然接到任务要切换到其他分支修复一个bug,但当前分支的开发并没有做好,所以还不能提交,如果强行切换分支,那么我们的修改将会丢失,这时我们需要用git stash命令,等处理完其他任务切换回来时,再将之前保存的修改应用即可(切换回之前的分支时使用命令git unstash)。

遴选(Cherry Pick)

将某个分支某个提交的修改应用到当前分支,作为一次新的提交。使用命令git cherry-pick。

移动HEAD

HEAD指向的是某个分支某次提交,HEAD在哪里,那么我们在Android studio中看到的代码就是某个提交的代码状态。在Android studio中如果要移动到之前的某一个提交,则选择要移动到的提交记录,然后单击鼠标右键,在弹出的菜单选项中选择“Checkout Revision”即可。

Git初始化配置

初次使用git时,我们都需要先配置下自己的 Git 工作环境。配置工作只需一次,以后升级时还会沿用现在的配置。当然,如果需要,你随时可以用相同的命令修改已有的配置。
Git 提供了一个叫做 git config 的命令来配置或读取相应的工作环境变量而正是由这些环境变量,决定了 Git 在各个环节的具体工作方式和行为。这些变量可以存放在以下三个不同的地方:

  • /etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。该文件在git的下载目录中。
  • ~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global 选项,读写的就是这个文件。该文件在c盘的用户目录中。
  • .git/config 文件:当前项目的 Git 目录中的配置文件(也就是工作目录中的 .git/config 文件)这里的配置仅仅针对当前项目有效。

以Windows系统为例,Windows系统的单用户多进程的系统,~/.gitconfig文件只在当前用户下生效,一旦切换用户那么该文件是没有用的;而/etc/gitconfig文件则是对Windows下创建的所有用户都有效。
注意:每一个级别的配置都会覆盖上层的相同配置。

用户信息

第一个要配置的是你个人的用户名称和电子邮件地址。这两条配置很重要,每次 Git 提交时都会引用这两条信息,说明是谁提交了更新,所以会随更新内容一起被永久纳入历史记录:
$ git config --global user.name “xxx”
$ git config --global user.email [email protected]
要检查已有的配置信息,可以使用 git config --list 命令;删除配置信息 git config --global --unset user.email

.git目录

在这里插入图片描述

文件名 作用
hooks 目录包含客户端或服务端的钩子脚本
info 包含一个全局性排除文件,作用与.gitignore文件差不多,写在文件中的文件将不被纳入git版本管理
logs 保存日志信息,git log命令读取的就是该目录里面的日志信息
objects 版本库,存储了所有的数据内容,就像是git的数据库
refs 存储指向数据的提交对象的指针(即分支)
config 文件包含了项目特有的配置选项
description 显示对仓库的描述信息
HEAD 指示当前的分支
index 使用git add命令都会将信息存储在该文件中,如果index中有相同文件名,那该文件会被覆盖

git的三大对象

Git的核心部分是一个简单的键值对数据库。可以向该数据库插入任意类型的内容,它会返回一个键值(hash值),通过该键值可以在任意时刻检索该内容。

  • git对象
    开发者每修改一个文件都会生成一个git对象,因此git对象不能代表一个项目的版本,因为一个项目的版本可能会修改多个文件,而树对象能够代表一个项目的版本。
向数据库写入内容 并返回对应键值 
命令:
    echo 'test content' | git hash-object -w --stdin 
-w 选项指示 hash-object 命令存储数据对象;若不指定此选项,则该命令仅返回对应的键值 
--stdin(standard input)选项则指示该命令从标准输入读取内容;
若不指定此选项,则须在命令尾部给出待存储文件的路径 
git hash-object -w 文件路径 存文件 
git hash-object 文件路径  返回对应文件的键值 d670460b4b4aece5915caf5c68d12f560a9fe3e4 

返回: 
    该命令输出一个长度为 40 个字符的校验和。 这是一个 SHA-1 哈希值

查看 Git 是如何存储数据的 
命令: 
     find .git/objects -type f 
返回: 
    .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 
这就是开始时 Git 存储内容的方式:一个文件对应一条内容。校验和的前两个字符用于命名子目录,余下的 38 个字符则用作文件名。

 git cat-file -p hash: 拿对应对象的内容
 git cat-file -t hash: 拿对应对象的类型

注意:当前操作都是在对本地数据库进行操作,直接就是工作区与版本库进行交互,不涉及暂存区。通过上述操作,我们只保存了文件内容并没有保存文件名

  • 树对象
    树对象(tree object),它能解决文件名保存的问题,也允许我们将多个文件组织到一起。Git 以一种类似于 UNIX 文件系统的方式存储内容。所有内容均以树对象和数据对象(git 对象)的形式存储,其中树对象对应了 UNIX 中的目录项,数据对象(git 对象)则大致上对应文件内容。一个树对象包含了一条或多条记录(每条记录含有一个指向 git 对象或者子树对象的 SHA-1 指针,以及相应的模式、类型、文件名信息)。一个树对象也可以包含另一个树对象。
操作 
1. 利用 update-index 命令 为 test.txt 文件的首个版本——创建一个暂存区。并通过 write-tree 命令生成树对像。
命令:
      git update-index --add --cacheinfo 100644 83baae61804e65cc73a7201a7252750c76066a30 test.txt 
      git write-tree
       
文件模式为 100644,表明这是一个普通文件 
          100755,表示一个可执行文件; 
          120000,表示一个符号链接。
--add 选项: 
    因为此前该文件并不在暂存区中 首次需要—add 
--cacheinfo 选项: 
    因为将要添加的文件位于 Git 数据库中,而不是位于当前目录下 所有需要—cacheinfo
   
2. 将第一个树对象加入第二个树对象,使其成为新的树对象
命令: 
    git read-tree --prefix=bak d8329fc1cc938780ffdd9f94e0d364e0ea74f579(树对象的hash值) 
    git write-tree 
    read-tree 命令,可以把树对象读入暂存区
 
3.查看暂存区当前的样子
     git ls-files -s 

4.查看树对象 
命令: 
     git cat-file -p master^{tree}(或者是树对象的 hash) master^{tree} 语法表示 master 分支上最新的提交所指向的树对象。

在这里插入图片描述

  • 提交对象
创建提交对象 
     echo 'first commit' | git commit-tree d8329f 
返回:
     fdf4fc3344e67ab068f836878b6c4951e3b15f3d
查看提交对象 
     git cat-file -p fdf4fc3 
返回: 
     tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
     author Scott Chacon <[email protected]> 1243
     committer Scott Chacon <[email protected]> 1243
     first commit

注意:git commit-tree 不但生成提交对象 而且会将对应的快照(树对象)提交到本地库中

Git后悔药

工作区
    如何撤回自己在工作目录中的修改 : git checkout --filename
暂存区
    如何何撤回自己的暂存  : git reset HEAD filename
版本库              
    如何撤回自己的提交(实际上提交对象是不会被删的): git commit --amend,本质是重新给用户一次机会改注释,并不是真正的后悔药

reset三部曲

git reset --soft commithash    ---> 用commithash的内容重置HEAD内容
git reset [--mixed] commithash ---> 用commithash的内容重置HEAD内容 重置暂存区
git reset --hard commithash    ---> 用commithash的内容重置HEAD内容 重置暂存区 重置工作目录
git reset [--mixed] commithash filename   --> 用commithash中filename的内容重置暂存区,不会重置HEAD内容

checkout深入理解

git checkout brancname  跟   git reset --hard commithash特别像
    共同点
        都需要重置 HEAD   暂存区   工作目录
    区别
         checkout对工作目录是安全的,意味着在工作区中新增文件时,如果没有加入到git中,该文件不会被删除    
         reset --hard是强制覆盖,没有纳入git管理的文件会被删除
         checkout动HEAD时不会带着分支走而是切换分支
         reset --hard时是带着分支走
         
checkout + 路径
      git checkout commithash  filename   
           重置暂存区
           重置工作目录
      git checkout -- filename  
          重置工作目录 

猜你喜欢

转载自blog.csdn.net/qq_36828822/article/details/105948397