Git基本命令


作者: 康凯森

日期: 2016-04-03

分类: 笔记


git基础

直接记录快照,而非差异比较 近乎所有操作都是本地执行

时刻保持数据完整性

在保存到 Git 之前,所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和索引 Git 使用 SHA-1 算法计算数据的校验和,通过对文件的内容或目录的结构计算出一个 SHA-1 哈希值,作为指纹字符串 该字串由 40 个十六进制字符(0-9 及 a-f)组成 所有保存在 Git 数据库中的东西都是用此哈希值来作索引的,而不是靠文件名。

文件的三种状态

在 Git 内都只有三种状态:已提交(committed),已修改(modified)和已暂存(staged)。

已提交表示该文件已经被安全地保存在本地数据库中了;已修改表示修改了某个文件,但还没有提交保存;已暂存表示把已修改的文件放在下次提交时要保存的清单中。

文件流转的三个工作区域:Git 的工作目录,暂存区域,以及本地仓库。

.git 的目录是 Git 用来保存元数据和对象数据库的地方

基本的 Git 工作流程如下:

在工作目录中修改某些文件。 对修改后的文件进行快照,然后保存到暂存区域。 提交更新,将保存在暂存区域的文件快照永久转储到 Git 目录中。

自动补全

下载 Git 的源代码,进入 contrib/completion 目录
cp git-completion.bash ~/.git-completion.bash
source ~/.git-completion.bash

git 配置

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
$ git config --global core.editor emacs
$ git config --global merge.tool vimdiff

git help config

git是什么

Git是分布式版本控制系统 屏幕快照 2016-04-03 下午11.24.38.png-289.6kB

建立仓库

#全局设置
git config --global user.name "kangkaisen"
git config --global user.email "kangkaisen@live.com"

#创建版本库
git init projectname

# 克隆
git clone [-b 分支名] git@github.com:michaelliao/gitskills.git [新目录名]

提交更新

工作目录下面的所有文件都不外乎这两种状态:已跟踪或未跟踪

已跟踪的文件是指本来就被纳入版本控制管理的文件,在上次快照中有它们的记录,工作一段时间后,它们的状态可能是未更新,已修改或者已放入暂存区。

只要在 “Changes to be committed” 这行下面的,就说明是已暂存状态。

其实 git add 的潜台词就是把目标文件快照放入暂存区域,也就是 add file into staged area,同时未曾跟踪过的文件标记为需要跟踪

出现在 “Changes not staged for commit” 这行下面,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。要暂存这次更新,需要运行 git add 命令

git file status.png-15.8kB

忽略文件

.gitignore

# 此为注释 – 将被 Git 忽略
# 忽略所有 .a 结尾的文件
*.a
# 但 lib.a 除外
!lib.a
# 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
/TODO
# 忽略 build/ 目录下的所有文件
build/
# 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
doc/*.txt
# ignore all .txt files in the doc/ directory
doc/**/*.txt

git 删除


git rm --cached readme.txt
删除暂存区域但不删除当前工作目录

移动文件

git mv file_from file_to

mv README.txt README
git rm README.txt
git add README


git add -A .
将批量移动的文件提交到暂存区

查看log

git log 

-p 选项展开显示每次提交的内容差异
-2 则仅显示最近的两次更新

git log --pretty=format:"%h - %an, %ar : %s"

git log --oneline
显示log简要信息

git log --oneline -n3

git log --stat
显示log中哪些文件被更改了,以及每个文件相对的增删行数。

git log --patch
显示log中每次提交的具体改动

git log --graph --all --decorate --oneline
显示提交的分支演变

查看 ignore 文件

git ls-files --others --ignored --exclude-standard

查看仓库状态

## 仓库当前的状态
git status

## 查看修改内容
git diff (filename)

## 查看提交历史
git log

## 查看文件更改历史
git log --pretty=oneline 文件名

## 查看某个文件的某次修改详细信息
git show log_id

git log --oneline fail_on_empty -1

git diff

git diff
显示您的工作目录和staged之间的差异.

git diff --cached
显示index和最近的commit之间的差异.

git diff HEAD
显示您的工作目录和最新的commit之间的差异

git diff --word-diff
按单词显示差异

git checkout

git checkout这个命令有三个不同的作用:检出文件、检出提交和检出分支。

git 分支

Git 中的分支实际上仅是一个包含所指对象校验和(40 个字符长度 SHA-1 字串)的文件,所以创建和销毁一个分支就变得非常廉价。说白了,新建一个分支就是向一个文件写入 41 个字节(外加一个换行符)

### 创建分支
git branch dev

### 切换分支
git checkout dev

### 创建并切换分支
git checkout -b dev 

git checkout -b KYLIN-1323 github/KYLIN-1323 


### 命令查看当前分支
git branch

### 查看所有分支
git branch -va

### 合并指定分支到当前分支
git merge dev  

单线的历史分支不存在任何需要解决的分歧,所以这种合并过程可以称为快进(Fast forward)。

### 删除分支
git branch -d dev 

git branch -D zerorow
### 推送分支
git push origin dev

### 删除远程分支
git push origin :serverfix

git rebase

有了 rebase 命令,就可以把在一个分支里提交的改变移到另一个分支里重放一遍。

衍合能产生一个更为整洁的提交历史

git rebase --onto master server client
取出 client 分支,找出 client 分支和 server 分支的共同祖先之后的变化,然后把它们在 master 上重演一遍

$ git checkout master
$ git merge client

git rebase [主分支] [特性分支] 命令会先取出特性分支 server,然后在主分支 master 上重演:

git rebase master server
$ git checkout master
$ git merge server

如果把衍合当成一种在推送之前清理提交历史的手段,而且仅仅衍合那些尚未公开的提交对象,就没问题。如果衍合那些已经公开的提交对象,并且已经有人基于这些提交对象开展了后续开发工作的话,就会出现叫人沮丧的麻烦。

本地无法直接 git push 时

git pull --rebase 后再push

遇到冲突时的分支合并

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

git merge --abort

改变和同步

## 把文件添加到仓库
git add readme.txt

git add -u
## 把文件提交到仓库
git commit -m "wrote a readme file"

第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

## 版本回退
git reset HEAD 文件名
git reset --hard HEAD^
git reset --hard 3628164
git reset --hard origin/mt_1.5-staging

## 丢弃工作区的修改
git checkout -- readme.txt  

命令git checkout --readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

## 删除
git rm test.txt

### 误删恢复
git checkout -- test.txt

## 创建SSH key
 ssh-keygen -t rsa -C "youremail@example.com"
 在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
## 关联远程库
 git remote add origin git@github.com:michaelliao/learngit.git
 远程库的名字就是origin
## 向远程推送修改
 git push -u origin master 第一次
 git push origin master

## 保存工作现场
git stash

## 回到工作现场
git stash pop

## 查看远程库
git remote

git remote -v

git remote rm origin
## 从远程抓取分支
git pull

远程仓库

git remote -v

git remote add [remote-name] git://github.com/paulboone/ticgit.git

git remote show origin

git remote rename pb paul

git remote rm paul

git fetch

git fetch [remote-name]

git fetch --all

git tag

git tag

git tag -l 'v1.4.2.*'

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

签署标签
git tag -s v1.5 -m 'my signed 1.5 tag'

验证标签
git tag -v v1.4.2.1

git push origin v1.5

git patch

git checkout -b 分支名

检查 patch 是否 没有冲突
git apply --check fail_on_empty.patch


生成patch

git format-patch github-master --stdout > KYLIN-1965.patch


           Ignore changes in whitespace at EOL.

       -b, --ignore-space-change
           Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other
           sequences of one or more whitespace characters to be equivalent.

       -w, --ignore-all-space

git format-patch mt_1.5-staging --stdout > KYLIN-1323.patch

合入patch1
git cherry-pick bd22e60


合入patch2
git am 0001-limit-log-function.patch

git am -3 --ignore-whitespace

git 查看某个文件所有历史版本

git log --follow -p 文件名

git show  356f6def9d3

git reset --hard 恢复

git reflog

git reset --hard 对应的commit。

git 恢复单个文件的历史版本

git log file

记录下需要恢复的commit版本号:如 9aa51d89799716aa68cff3f30c26f8815408e926

git reset 9aa51d89799716aa68cff3f30c26f8815408e926 file

git commit -m "llll"

代码回滚 撤销一个commit

git revert可以用在公共分支上,git reset应该用在私有分支上。

git revert当作撤销已经提交的更改,而git reset HEAD用来撤销没有提交的更改


想完全舍弃你没有提交的改动
git reset --hard HEAD~2 舍弃最近俩次的提交


Revert撤销一个提交的同时会创建一个新的提交
git revert HEAD~2

撤销 pull 操作

git reset --hard

修改最后一次提交

git commit -m "cuboid.size.ratio" --amend
git push origin kangkaisen -f

俩个commit 合为一个

git rebase -i <不變動的commit的SHA-1>
编辑 message 
要合并的commit 前 输入 s
wq 保存
输入新的commit message

rebase 历史记录的清晰

《OLAP 性能优化指南》欢迎 Star&共建

《OLAP 性能优化指南》

欢迎关注微信公众号