作者: 康凯森
日期: 2016-04-03
分类: 笔记
直接记录快照,而非差异比较 近乎所有操作都是本地执行
在保存到 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 config --global user.name "John Doe"
$ git config --global user.email [email protected]
$ git config --global core.editor emacs
$ git config --global merge.tool vimdiff
git help config
Git是分布式版本控制系统
#全局设置
git config --global user.name "kangkaisen"
git config --global user.email "[email protected]"
#创建版本库
git init projectname
# 克隆
git clone [-b 分支名] [email protected]:michaelliao/gitskills.git [新目录名]
工作目录下面的所有文件都不外乎这两种状态:已跟踪或未跟踪
已跟踪的文件是指本来就被纳入版本控制管理的文件,在上次快照中有它们的记录,工作一段时间后,它们的状态可能是未更新,已修改或者已放入暂存区。
只要在 “Changes to be committed” 这行下面的,就说明是已暂存状态。
其实 git add 的潜台词就是把目标文件快照放入暂存区域,也就是 add file into staged area,同时未曾跟踪过的文件标记为需要跟踪
出现在 “Changes not staged for commit” 这行下面,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。要暂存这次更新,需要运行 git add 命令
.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 rm --cached readme.txt
删除暂存区域但不删除当前工作目录
git mv file_from file_to
mv README.txt README
git rm README.txt
git add README
git add -A .
将批量移动的文件提交到暂存区
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
显示提交的分支演变
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
显示您的工作目录和staged之间的差异.
git diff --cached
显示index和最近的commit之间的差异.
git diff HEAD
显示您的工作目录和最新的commit之间的差异
git diff --word-diff
按单词显示差异
git checkout这个命令有三个不同的作用:检出文件、检出提交和检出分支。
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
有了 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 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 "[email protected]"
在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
## 关联远程库
git remote add origin [email protected]: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 [remote-name]
git fetch --all
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 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 log --follow -p 文件名
git show 356f6def9d3
git reflog
git reset --hard 对应的commit。
git log file
记录下需要恢复的commit版本号:如 9aa51d89799716aa68cff3f30c26f8815408e926
git reset 9aa51d89799716aa68cff3f30c26f8815408e926 file
git commit -m "llll"
git revert可以用在公共分支上,git reset应该用在私有分支上。
git revert当作撤销已经提交的更改,而git reset HEAD用来撤销没有提交的更改
想完全舍弃你没有提交的改动
git reset --hard HEAD~2 舍弃最近俩次的提交
Revert撤销一个提交的同时会创建一个新的提交
git revert HEAD~2
git reset --hard
git commit -m "cuboid.size.ratio" --amend
git push origin kangkaisen -f
git rebase -i <不變動的commit的SHA-1>
编辑 message
要合并的commit 前 输入 s
wq 保存
输入新的commit message
rebase 历史记录的清晰