前言

git 是什么

它是一个版本控制工具。 版本控制是一种记录一个或若干个文件内容变化,以便将来查阅特定版本修订情况的系统。 想想当年写毕业论文的情况,写了一个最终版,发现不行,在原来的基础上又修改下重新存为“最终版1”、“最终版2”、“打死也不改版1”、“打死也不改版2”…。如果自己知道有 git 这种强大的版本控制工具呢,肯定不会存好多版本,打开好多版本,来来回回的复制粘贴,简直蠢的要死。git 是在商业公司 BitKeeper 停止与 Linux 开源社区合作后,由 Linux 开源社区开发的版本控制工具。

git 基础操作

配置 git

/etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。

~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global 选项,读写的就是这个文件。

当前项目的 git 目录中的配置文件(也就是工作目录中的 .git/config 文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以 .git/config 里的配置会覆盖 /etc/gitconfig 中的同名变量。

配置用户信息

$ git config --global user.name “你的名字"
$ git config --global user.email “你的邮箱”

检查配置信息

$ git config --list
$ git config user.name //检查 git 的某一项配置,例如名字

gitignore 里配置需要忽略的文件。
养成初始化就配置 gitignore 文件的习惯,要不每回 git status 的时候会看到一大堆没必要提交的文件,Xcode 里可以做如下配置:

# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## Build generated
build/
DerivedData/

## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/

## Other
*.moved-aside
*.xccheckout
*.xcscmblueprint

## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM

# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/

# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build

# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control

fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output

# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode

iOSInjectionProject/

更多的配置可以参考 这里

获取 git 仓库

在现有目录中初始化仓库

$ git init

克隆现有的仓库

$ git clone <url>
$ git clone -b <branch> <url>

克隆一个带子模块的项目

$ git clone <url>
$ git submodule init
$ git submodule update

查看子模块的地址可以在项目目录的 .gitmodules 中查看。

基础命令

用 git 管理文件后,对于任何一个文件,在 git 内都只有三种状态:已提交(committed),已修改(modified)和已暂存(staged)。

已提交:表示该文件已经被安全地保存在本地数据库中了;

已修改:表示修改了某个文件,但还没有提交保存;

已暂存:表示把已修改的文件放在下次提交时要保存的清单中。

文件流转的三个工作区域:git 的工作目录,暂存区域,以及本地仓库。
从项目中取出某个版本的所有文件和目录,用以开始后续工作的叫做工作目录。这些文件实际上都是从 git 目录中的压缩对象数据库中提取出来的,接下来就可以在工作目录中对这些文件进行编辑。

所谓的暂存区域只不过是个简单的文件,一般都放在 git 目录中。有时候人们会把这个文件叫做索引文件,不过标准说法还是叫暂存区域。
基本的 git 工作流程如下:

  1. 在工作目录中修改某些文件。
  2. 对修改后的文件进行快照,然后保存到暂存区域。
  3. 提交更新,将保存在暂存区域的文件快照永久转储到 Git 目录中。
$ git status  //检查当前文件状态
$ git add . //添加文件到暂存区
$ git commit -m "message" //提交更新

其实 git add 的潜台词就是把目标文件快照放入暂存区域,也就是 add file into staged area,同时未曾跟踪过的文件标记为需要跟踪。这样就好理解后续 add 操作的实际意义了。它是一个多功能命令,可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。

移除文件

$ git rm 文件

删除文件但是让文件留在磁盘上

$ git rm --cached README

查看提交历史

$ git log
$ git log remote/aaa //查看远程分支 aaa 的日志

查看某一次提交修改的内容

$git show <commitid>

查看最近 n 次提交修改的内容

$git log -p -n

用 oneline 将每个提交放在一行显示

$ git log --pretty=oneline

用 ASCII 字符串表示的简单图形,形象地展示了每个提交所在的分支及其分化衍合情况

git log --pretty=format:"%h %s" --graph

format 常用的格式占位符写法及其代表的意义

选项 说明
%H 提交对象(commit)的完整哈希字串
%h 提交对象的简短哈希字串
%T 树对象(tree)的完整哈希字串
%t 树对象的简短哈希字串
%P 父对象(parent)的完整哈希字串
%p 父对象的简短哈希字串
%an 作者(author)的名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以用 -date= 选项定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者(committer)的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 提交日期,按多久以前的方式显示
%s 提交说明

例如,列出所有最近两周内的提交:

$ git log --since=2.weeks

git log 支持的选项

选项 说明
-p 按补丁格式显示每个更新之间的差异
–stat 显示每次更新的文件修改统计信息
–shortstat 只显示 –stat 中最后的行数修改添加移除统计
–name-only 仅在提交信息后显示已修改的文件清单
–name-status 显示新增、修改、删除的文件清单
–abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符
–relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)
–graph 显示 ASCII 图形表示的分支合并历史
–pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。

撤消对文件的修改

$ git checkout -- [file]

撤消对所有文件的修改

$ git checkout -- . 或者 $ git checkout .

显示还没有暂存起来的改动,不是这次工作和上次提交之间的差异

$ git diff

已经暂存起来的文件和上次提交时的快照之间的差异

$ git diff --cached //git 1.6.1 及更高版本还允许使用 git diff --staged,效果是相同的

git 别名

$ git config --global alias.st status

这意味着,当要输入 git status 时,只需要输入 git st。查看别名的位置可以使用上面提到的 git config -—list 命令。如果想要执行外部命令,可以在命令前面加入 ! 符号,操作如下:

git config --global alias.ls '!ls'

git 分支

分支基础

分支是 git 最大的亮点,也是它的杀手锏。git 的分支分为远程分支,远程跟踪分支和跟踪分支。

远程分支就是在远程仓库上的普通分支。

远程跟踪分支是在本地的只读的记录远程分支状态的分支,其指向用户无法移动,当你做任何网络通信操作时,它们会自动移动。

跟踪分支是从远程跟踪分支上生成的本地分支。

分支常用命令

查看分支

$ git branch

分支创建

$ git branch 分支名

分支切换

$ git checkout 分支名

查看每一个分支的最后一次提交

$ git branch -v

查看哪些分支已经合并到当前分支

$ git branch —merged

查看所有包含未合并工作的分支
$ git branch --no-merged

分支合并,如把 test 分支合并到 master 分支

$ git checkout master
$ git merge test

查看分支历史

$ git log --oneline --graph

新建一个分支并同时切换到该分支上

$ git checkout -b 分支名

删除分支

$ git branch -d 分支名

查看当前配置有哪些远程仓库

$ git remote

显示对应的克隆地址

$ git remote -v

添加远程仓库

$ git remote add [shortname] [url]

推送数据到远程仓库

$ git push origin master

远程仓库的重命名

$ git remote rename a b

远程仓库的删除

$ git remote rm xxx

查看远端仓库的详细信息

$ git remote show origin

某个远程仓库在本地的简短名称,比如想把 pb 改成 paul

$ git remote rename pb paul

git tag

打标签是我们经常用到的命令,通常是在发布新版本或者切换到以前的特定版本修改 bug 的时候用。
git 使用两种主要类型的标签:轻量标签(lightweight)与附注标签(annotated)。
轻量标签很像一个不会改变的分支,它只是一个特定提交的引用。
附注标签是存储在 git 数据库中的一个完整对象。
创建附注标签

$ git tag -a v1.4 -m 'my version 1.4’

创建轻量标签

$ git tag v1.4-lw

后期打标签

$ git tag -a v1.2 9fceb02 (需要在命令的末尾指定提交的校验和或部分校验和)

列出标签

$ git tag

把标签推送到远程仓库服务器上

$ git push origin [tagname]

检出标签(也就是在特定的标签上创建一个新分支)

$ git checkout -b version2 v2.0.0

本地配置多个 ssh key

为公司生成一对秘钥 ssh key

ssh-keygen -t rsa -C 'yourCompanyEmail@xx.com' -f ~/.ssh/gitlab-rsa

为 github 生成一对秘钥 ssh key

ssh-keygen -t rsa -C 'yourGithubEmail@xx.com' -f ~/.ssh/github-rsa

在 ~/.ssh 目录下新建名称为 config 的文件,内容如下:

# gitlab
Host gitlab.com
HostName gitlab.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/gitlab-rsa
# github
Host github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/github-rsa
# 配置文件参数
# Host : Host可以看作是一个你要识别的模式,对识别的模式,进行配置对应的的主机名和ssh文件
# HostName : 要登录主机的主机名
# User : 登录名
# IdentityFile : 指明上面User对应的identityFile路径

参考链接

https://git-scm.com/book/zh/v2