Git 学习笔记

随着软件工程的发展,开发者之间的合作开发变得越来越重要,为了解决不同开发者之间的协同开发问题,集中化的版本控制系统(CVCS,Centralized Version Control System)应运而生。

CVCS 固然提高了软件开发的效率,但是其也有一些缺陷。如果网络发生异常,或者中央服务器宕机,那么,开发人员就不能提交或更新数据了。并且,严重情况下,可能造成数据的丢失。所以,分布式的版本控制系统(DVCS,Distributed Version Control System)问世。

Git 简介

Git 就是分布式版本管理系统的一种,但不同于其他版本管理系统,其不是保存每个变更文件的差异,而是对所有的文件保存一次快照。这些保存在数据库中的快照数据都是以文件内容生成的哈希值,该值由 SHA-1 函数计算得到,能够保证数据的完整性,同时可知,对于未发生变化的文件,其哈希索引值是不变的,所以每个版本做一次快照保存并不意味着将所有的文件数据重复保存,它们的文件索引值都指向一份文件数据。

在 Git 中有三种状态,已修改,已暂存,已提交。

  • 已修改,表示工作目录中的文件发生了变更,但是并没有保存到暂存区或数据库中。
  • 已暂存,表示已修改的文件保存到了暂存区,并且其会在下一次提交时,保存到数据库中。
  • 已提交,表示暂存区中的数据已经保存到了数据库中。

Git 基本命令

  1. git config

    在 Git 中,可以自定义一些配置,这些配置可以是针对所有用户的,也可以只针对当前用户,同样,可以只作用于当前版本库。

    • –system 作用于所有用户的配置,配置一般保存在 /etc/.gitconfig 文件中

    • –global 作用于当前用户的配置,配置一般保存在 ~/.gitconfig 文件中

    • –local 作用于当前仓库的配置,配置一般保存在仓库的 .git/config 文件中,该选项为默认选项

      如设置一些别名来简化命令:

      1
      2
      3
      $git config --global alias.st status
      $git config --global alias.unstage 'reset HEAD --'
      $git config --global alias.list '!ls -la'
> 作用范围小的配置会覆盖作用范围大的配置
  1. git init

    将当前目录初始化为一个版本管理库

  2. git clone

    克隆远程仓库到本地

  3. git status

    查看当前仓库的状态

  4. git diff

    查看工作目录中的文件同暂存区中文件的区别,使用 --staged--cached 选项则可以查看暂存区同最后一次提交的文件区别。

  5. git add

    将修改的文件加入到暂存区,该命令除了可以添加新文件和被改动的文件,还可以表示冲突文件已经修改完毕。

  6. git commit

    提交已暂存的数据,执行该命令时,会打开编辑器要求输入提交注释,如果不添加注释,则无法提交成功。

    使用 -m 选项可以直接添加注释,另外,使用 -am 选项可以将添加和提交合为一个操作。

    另外,--amend 选项可以用来修改最后一次提交,表面上看,似乎似将当前暂存区中的修改追加到了最后一次提交上。

  7. git reset

    撤销提交,或者取消暂存区中的修改。

  8. git checkout

    取消工作目录下的修改,其实质是拷贝了暂存区中的文件来覆盖工作目录下修改的文件,所以该命令会造成数据的不可追溯,应慎用。

  9. git rm

    将指定文件从 git 的工作目录中删除,并且 git 仓库也不会再对该文件进行跟踪,如果暂存区中存在该文件,那么说明该文件被修改了且未提交,此时删除文件会造成修改的永远丢失,所以应先进行提交,当然,也可以使用 -f 选项强制删除。

    使用 --cached 选项可以将指定文件从仓库即暂存区中删除,但是该文件仍然保留在工作目录下,例如,当想要移除某些跟踪的文件,但想将其保留在工作目录下,便可以使用该命令,而后将文件加入的忽略配置文件中。

  10. git mv

    移动文件,使用该命令可以对文件进行重命名。

  11. git log

    查看提交历史,使用一些选项,可以帮助日志的查看。

    1
    2
    3
    4
    5
    6
    7
    8
    //显示出每次提交的差异
    $git log -p

    //显示出最近指定条数的提交
    $git log -3

    //显示分支图形
    $git log --pretty=format:"%an" --graph

在使用这些命令时,需要查看命令帮助,查看方式有很多种,以 git log 为例,可使用下面的方式查看帮助:

$man git-log

$git log –help

$git help log

$git help git-log

还可以用下面的命令将帮助手册转为 PDF 文档进行查看:

$man -t git-log | open -a Preview -f

变基

除了 git merge 命令外,使用 git rebase 也可以合并分支,这种合并方式实际是将一个分支上的提交移动到另外一个分支上。

如要将 dev 分支上的新增提交移动到 master 分支上,可执行下面的命令:

1
2
$git checkout dev
$git rebase master

在进行变基前,要先处于待移动分支上,但是也可以直接指定两个分支,从而不必进行分支的切换。

1
$git rebase master dev

在变基的过程中,若发生冲突,则先解决冲突并将其添加到暂存区,但是不能进行提交,而是应执行继续变基命令,再进行快速合并。

1
2
3
$git rebase --continue
$git checkout master
$git merge dev

另外,其有一个 --onto 选项可以用来变基分支的分支,如,A 分支有一个 B 分支,而 B 分支有一个 C 分支,现在只是想将 C 分支变基到 A 分支,那么可以执行下面的命令:

1
$git rebase --onto A B C

该命令会寻找 B 分支和 C 分支的最近的共同祖先,而后将其在 C 分支上的所有修改变基到 A 分支上。

使用这个命令可以选择性的删除中间提交,假设在 dev 分支上有连续 3 个提交,现在想移除中间的 commit-B 提交:

1
[base-commit] <- [commit-A] <- [commit-B] <- [commit-C] <- dev

第一步,基于 commit-B 提交和 commit-C 提交创建两个分支 branch-B 和 branch-C :

1
2
3
4
5
6
7
8
9
10
$git checkout branch-B commit-B
$git checkout branch-C commit-C

[base-commit] <- [commit-A] <- [commit-B] <- [commit-C] <- dev
^ ^
| |
branch_B branch_C
```

第二步,回滚 dev 分支到 commit-A 提交:

$git reset commit-A

[base-commit] <- [commit-A] <- [commit-B] <- [commit-C]
^ ^ ^
| | |
dev branch_B branch_C

1
2

第三步,执行变基命令:

$git rebase –onto dev branch-B branch-C

[commit-C] <- branch_C
    |
    ∨

[base-commit] <- [commit-A] <- [commit-B]
^ ^
| |
dev branch_B

1
2

第四步,快速合并并删除多余的分支:

$git merge branch-C
$git branch -d branch-B
$git branch -d branch-C

[base-commit] <- [commit-A] <- [commit-C] <- dev

Newer Post

NSLayoutAnchor

在 iOS 9.0 之后,UIView 中新增了一个 UIViewLayoutConstraintCreation 分类,该分类声明了一些 NSLayoutAnchor 属性,用来简化视图约束的创建。 NSLayoutAnchor 虽然给出了 NSLayoutXAxisAnchor、NSLayout …

继续阅读