Git权威指南 阅读
Git权威指南
git
版本控制软件,文章中把这种分布式的版本控制软件与其前身Subversion做比较,svn我没有使用过;原来对git的使用也基本上只局限于常用的指令,比如commit、branch、checkout、push、pull等,而且基本都是比较基础的用法,对于命令的参数也不太熟悉,通过阅读书籍以及实际操作记录下新的命令。
命令记录
git --version
// 初始化配置
git config --global user.name "username"
git config --global user.email user@email.com
// 设置别名(应该是满足svn用户习惯
sudo git config --system alias.st status
sudo git config --system alias.ci commit
// 初始化仓库
git init <repo_name>
// git add命令可以把修改的内容加入暂存区
git add -u // 添加所有修改的文件
git add -A // 添加本地新增或者删除的文件
git add -p // 预览修改并且有选择的添加
git grep // 查找纳入管理的文件内容
git rev-parse --git-dir // 查看版本库.git所在位置
git rev-parse --show-toplevel // 显示工作区根目录
git rev-parse --show-prefix // 显示相对于工作区根目录的相对目录
git rev-parse --show-cdup // 显示从当前目录后退到工作区根目录的深
git config -e // 可以打开当前repo的配置文件修改,也可以提供参数 --global 用户全局配置 --system 系统级配置
git config <section>.<key> // 直接读取对应的参数
git config <section>.<key> <value> // 直接修改对应的参数
git config --unset // 删除配置
git commit --amend --allow-empty --reset-author // amend参数修改上次提交,allow-empty允许没有用户名邮箱,reset-author修改提交的user信息
git clone -l -s -n . ../copy // 把项目clone到本地一份
可以直接通过 man
命令查看帮助,或者等效于 git --help
,默认通过分页器进行输出,在分页器中按 h
可以查看帮助,常用的按键命令:
q:退出
h:查看帮助
空格键向下翻页,b向上翻页
d和u分别向下与向上翻半页;j与k向上与向下翻一行
/pattern 向下寻找pattern匹配的内容
?pattern向上寻找匹配的内容
n或者N表示继续寻找下一个或者上一个
g:跳到第一行;G:跳到最后一行;输入数字加g:跳转到数字行
!
奇怪的命令
git format-patch v1..HEAD
git send-email *.patch
git grep
git commit --amend // 对上次commit的信息进行修改
git rebase -i
git 暂存区
.git/index 维护着一个虚拟的工作区目录。除了工作区本身的目录,还有版本库中维护的暂存区的目录,以及master分支指向的目录
执行 git reset HEAD 命令时,暂存区的目录会被HEAD替换,工作区不受影响
执行 git remove --cahced
执行 git checkout HEAD . 非常危险,会用master分支上全部文件替换掉暂存区以及工作区上的文件,工作区中没有提交的修改以及在暂存区中的修改也会被重置
git 对象
git中的对象(比如提交、树、文件变更)等都会用40位的SHA1哈希值表示,这些对象存储在仓库的 .git
目录下,通过 git log
命令可以查看commit记录信息,比如
// git log --pretty=raw
commit 021449d1080ef26d0a8149d4e6af88209e42d81e
tree 3111d544242fdef3aec4cc4b07b188aa756ba2d9
author chuyuxuan <> 1686041498 +0800
committer chuyuxuan <> 1686041547 +0800
change commit message;commit test
使用 git cat-file -t
命令可以查看对象类型, 使用 git cat-file -p
命令可以查看对象具体内容
查看一个树可以看到这个分支包含的全部文件,这里的每个文件也都是一个git对象,类型是blob,内容就是当时的文件内容,这些对象都存储在 .git/objects
目录下,用对象的前两位做次级目录进行分类
.git/refs
目录保存引用,.git/refs/heads
目录下的引用就是分支.
计算sha值:看看怎么做的
-- git cat-file commit HEAD | wc -c
200
-- (printf "commit 200\000";git cat-file commit HEAD)| shasum
021449d1080ef26d0a8149d4e6af88209e42d81e -
-- git rev-parse HEAD
021449d1080ef26d0a8149d4e6af88209e42d81e
使用 HEAD 可以表示版本库中的最近一次的提交,使用^ 表示上次的提交,多个父提交可以在 ^后表明数字来指定是哪个父提交
也可以使用<n>来表示祖先提交,HEAD5 等同于 HEAD-^^^^^-
git reset
git reset [-q] [commit] [--]
使用在commit状态下 paths中的文件重置当前暂存区的文件,默认commit是HEAD
git reset [--soft|--hard|--mixed|--merge|--keep] [commit]
根据不同的选项对工作区或者暂存区的文件进行重制
git reset -- filename 添加文件的反向操作
What's the difference between git reset --mixed, --soft, and --hard?
git checkout
git checkout [-q] [commit] [--]
默认从暂存区进行检出,相当于使用暂存区的修改替换工作区的修改,不改变HEAD
git checkout [
进行切换分支,如果不加branch相当于进行工作区状态检查
git checkout [-m] [[-b|--orphan] new_branch] [<start_point>]
创建并切换到新的分支
git stash
git stash
git stash list
git stash pop [stash]
从某个stash恢复
git stash apply
从stash中恢复,但是保留stash的记录
git stash [save [
上面git stash的完整版,可以提供信息
git stash drop [stash]
删除一个stash,默认最新
git stash clear
删除所有储存的进度
git rev-list
git blame
查询一个具体文件的各行都是谁先提交的,用于定位问题
git bisect
在各个版本上进行判断,找到最近的坏提交;支持脚本进行自动化判断
git历史穿梭
这部分主要分为几部分,首先说明浏览提交信息(git log)、版本范围的表示方法(git rev-list);
对前一个或者几个提交的变更(悔棋
git commit --amend 或者 git reset --soft
变更某次提交导致后续提交发生变化(改变时间线
git cherry-pick
git rebase
git rebase --onto
先checkout到till
把since..till范围的提交写到一个临时文件中
将当前分支重置到newbase
从保存的临时文件的提交记录中,逐一提交记录
提交遇到已提交过的,跳过;遇到冲突提示用户解决
A-B-C-D-E-F如果想抛弃D提交
git rebase --onto C E^ F 等价于git rebase --onto C D
删除提交的历史记录
希望在tag A前的提交记录都删除,则可以构造一个以A为根提交,在将A之后的提交rebase到新的节点上
创建根提交
git commit-tree
git hash-object
反转提交
git revert
提交之后再反向提交,避免“覆水难收”
git协作
常见的命令 clone push pull
合并时树冲突问题:双方都对文件目录进行了修改,导致合并的时候出现了冲突
解决方案:在遇到冲突时,根绝实际情况解决,一般情况下可以使用git rm移除冲突的文件之一,然后用git add决定保留文件,最后commit
git merge不同的合并策略
git tag 有轻量级的里程碑与完整的里程碑,轻量级的没有commit信息,没有设立里程碑的用户信息
里程碑一旦设立,最好不要随意修改;里程碑的共享必须显式的推送给远端,并且本地与远端存在同名的里程碑,本地不会同步,即使这两个对象不同;可以往远端推送一个空值来删除里程碑。
git branch -m 重命名分支
分支合并的变基操作
普通的merge,在G处merge的时候,需要review3个commit的代码(E,F以及merge的commit)
A - B - C - D - G
\ /
E ---- F
使用rebase
在开发分支上 git rebase master
A - B - C - D
\
E - F
这里只有E、F两个commit
执行变基指令时,步骤:先checkout到开发分支(即E F提交在的分支),然后记录提交到临时文件,然后强制切换到master分支(这时候是D)并把提交一一拣选到开发分支上。这时候开发分支上已经包含全部提交了,然后切换到master上merge dev,就能执行fast forward
关于merge与rebase,可以看看 这个文章 ,有动图说明比较详细
git remote
在 .git/config
文件中有个包含[remote]的配置(随便找的一个repo
[remote "origin"]
url = https://github.com/ossxp-com/gitdemo-commit-tree.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch会把所有远程分支拿到本地,也可以git remote add添加新的远程版本库
git 协作模型
参考 常见模型