git学习笔记
配置Git
git config --global core.editor "code --wait"
: 指定vscode作为全局编辑器.git config --global diff.tool vscode
: 设置通过vscode查看文件变更.git config --global difftool.vscode.cmd "code --wait --diff $LOCAL $REMOTE"
: 配置git打开vscode的命令参数.git config --global -e
: 使用全局编辑器编辑配置文件.git config --global core.autocrlf input
: 配置换行符windows的换行符是
\r\n
, 而mac是\n
, 如果配置错误就会在使用git时出现很多不必要的麻烦.- Mac:
core.autocrlf input
- Win:
core.autocrlf true
通常在git安装时会自动配置, 知道原理即可.
- Mac:
git config --global init.defaultBranch <name>
: 设置git默认分支名称, 未设置默认为master
, 但是初始化git时会有额外的提示信息.git config --global alias.lg "log --pretty=format:'%an -> %h'"
: 为git命令创建别名, 可以通过别名将复杂的git命令和参数进行简化.一个自用的简略信息:
%Cgreen%an<%ae>%Creset->%Cblue%h%Creset@%as:%Cred%s%Creset
git config --global core.pager=cat
: 设置git命令的输出分页器, 默认使用less, 会将结果单独显示在一个屏幕中, 需要按q
才能退出, 原始终端则没有内容. 改为cat
则直接在当前命令行输出, 根据个人偏好配置即可.
Git 命令行工具
仓库管理
git init
: 初始化git目录, 自动创建.git
文件夹.git status
: 查看当前git状态. 也可结合参数-s
显示简略信息.git add [option]
: 将变更内容添加到缓存区.git commit -m"commit message"
: 提交到本地仓库.如果设置了git的全局编辑器, 可以直接使用
git commit
, 此时会使用指定的编辑器打开一个文本文件, 可以更为方便的输入提交描述.git commit -am "commit message"
: 跳过缓存, 直接将全部修改提交到本地仓库.
文件操作
git ls-files
: 显示git管理的文件.git rm [file]
: 在git和本地同时删除指定文件.git rm --cached [file]
: 仅删除git缓存的文件, 本地文件不受影响.git mv [file]
: 在本地和git中同时移动或者重命名文件.git restore [file]
: 将本地已有索引的文件恢复至修改前的状态.--staged
: 将缓存区的内容回复至之前的状态.--source=[HEAD~n | id] filename
: 将修改或删除的文件恢复到之前提交的版本.
git clean
: 删除所有未创建索引的内容, 危险操作, 需要配合参数执行.-f
: force强制执行-d
: 包含文件夹
源码管理
git diff
: 显示缓存区与工作区的变动--staged
: 查看缓存区的变动内容.HEAD~2 HEAD [filename]
: 查看最近3次的全部或特定文件的变化.
git log
: 显示提交记录--oneline
: 显示提交记录摘要--reverse
: 逆序显示
git show
: 显示最后一次提交的变更内容HEAD~n
: HEAD代表最后一次提交,n
表示向前数n次, 比如HEAD~n
- 也可以通过log查看提交id, 通过指定id查看提交内容.
HEAD:path/to/file
: 查看特定文件的变动.HEAD --name-status
: 查看更改的文件.
git checkout [id]
: 将工作区恢复至指定的快照id.HEAD~n
: 向前数n个快照.master
: 设置为最新的快照.
查找bug
当一个快照出现问题, 而这个问题有可能是由于之前的快照索引的, 那么诸葛快照查找就会非常麻烦.
为了这种情况, git 提供了一个强大的工具, bisect
. bisection的缩写, 本质就是采用二分法查找出错的快照.
git bisect start
: 开始二分查找git bisect bad
: 标记当前快照有问题, 通常在master快照下执行git bisect good [id | HEAD~n]
: 指定之前的一个确定没问题的快照, 此时bisect会自动帮助我们在不同的快照之间进行切换, 用以检查错误.git bisect good
: 标记当前检查的快照正常, bisect会自动切换至下一个快照git bisect bad
: 标记该快照为异常快照git bisect reset
: 退出bisect模式.
设置快照标签
git tag v1.0.0
: 设置当前快照的标签为v1.0.0
git tag empty d873716 -m "empty project"
: 为指定id的快照添加empty标签, 同时设置标签信息.git checkout empty
: 根据标签checkoutgit tag -n
: 列出所有标签和标签信息.git tag --points-at <id>
: 列出指定或者当前快照的标签git tag -d [tagname]
: 删除标签
.gitignore文件
在根目录下建立.gitignore
文件用以配置忽略版本控制的文件.
1
2
3
logs/ # 忽略logs目录
main.log # 忽略指定文件
*.log # 忽略匹配文件
对于已经加入git索引的内容不会受到
.gitignore
文件的影响.需要通过
git rm --cached
命令手动将其在索引中删除.
Git可视化软件
Sourcetree: 完全免费, 仅支持Windows和Mac.
GitKraken: 针对开源软件项目免费. UI是相当的舒服~~
Git 分支管理
git的分支是一个指向master
快照的指针, 并不会创建新的文件系统, 所以不会像svn一样产生额外的消耗.
git branch bugfix
: 创建名为bugfix的分支git branch
: 列出所有分支git switch bugfix
: 切换到bugfix分支git switch -C bugfix
: 创建并切换到bugfix分支git branch -m bugfix bugfix-somebug
: 重命名分支git branch -d bugfix-somebug
: 删除指定分支, 如果分支存在未合并的内容则无法删除. 在确定删除的情况下可以使用-D
强制执行.git branch --merged
: 显示已经合并的分支git branch --no-merged
: 显示尚未合并的分支
确定两个分支之间的不同
git log master..bugfix-somebug
: 显示分支之后的提交内容.git diff master..bugfix-somebug
: 显示两个分支之间的差异.如果当前已经在master分之下, 可以省略
master..
git diff --name-only bugfix-somebug
: 显示有差异的文件.git diff --name-status bugfix-somebug
: 显示有差异的文件状态.比较实用的命令, 可以创建两个别名, 比如
dno
,dns
通过stash缓存变动内容
在工作区发生了变动, 并且没有进行提交时, 如果需要切换到其他的分支, 可以将变动内容暂存以备之后使用.
git stash push -m "stash message"
: 将工作区的变动内容移至暂存区.- 如果工作区包含为索引的内容, 可以使用
-am
参数, 即--all -m
.
- 如果工作区包含为索引的内容, 可以使用
git stash list
: 列出暂存区索引.git stash show n
: 显示第n条暂存内容的变更项.git stash apply n
: 取回暂存区的第n个索引.git stash drop n
: 删除第n项git stash clear
: 清空暂存区
合并分支
合并分支大致分为两种情况:
对于第一种情况来说, 合并分支非常简单, 只需要在master
分支下执行合并命令即可;
1
git merge bugfix-somebug
如果不希望使用Fast Forward
可以添加参数--no-ff
. 这样当前的master就会和分支合并为一个新的快照.
有些公司会禁用FF合并, 因为这会让项目的演化信息丢失, 整个项目的研发路线成为一条支线. 如果在应用分之后希望退回之前的状态, 那么就需要找到建立分支时的快照.
但不使用FF的情况下无论何时想要取消合并只需要回退一步就可以了.
也可以通过git配置禁用FF从而省略关键字:
1
2
git config merge.ff false # 当前工作区禁用
git config --global merge.ff false # 全局禁用
还有一种不太常用的合并方式, git merge --squash branch
. 直译压缩合并.
会将指定分支中的变动内容加入到当前分支, 可以直接使其为对当前分支的修改. 但本质上并没有将分支合并到主分支上.
因此只适用于较小变动的分支, 且应当在合并操作之后将分支删除.
因为虽然压缩合并已经将分支内容写入了主分支内, 但是通过git branch --merged
命令查看已经合并的分支时不会显示压缩合并的分支. 这会产生歧义, 无法判断该分支是否已经被正确处理了.
解决合并冲突
当合并两个分支时, 如果他们对同一个文件进行过修改提交时就会出现冲突(conflicts). 此时通过git status
查看产生冲突的文件, 手动选择需要保留的代码并提交即可.
在使用GitKraken一类功能强大的可视化工具时可以很好的解决合并分支和冲突问题.
但GitKranken只针对开源项目免费.
也有一些免费的合并工具, 比如P4Merge
可以通过git全局设置来指定默认的合并工具
1
2
git config --global merge.tool p4merge
git config --global mergetool.p4merge.path "/Applications/p4merge.app/Contents/MacOS/p4merge"
配置完成后, 当出现冲突时就可以直接使用git mergetool
启动工具.
如果希望中止合并, 可以直接使用命令git merge --abort
.
p4merge会自动为冲突文件创建副本, 而git则会询问这一副本文件.
可以在
.gitignore
文件中添加备份文件*.orig
或直接通过全局配置禁用备份:
1 git config --global mergetool.keepBackup false
撤销提交
如果希望撤销一个提交, 可以通过命令 git reset [mode] HEAD~1
完成.
撤销命令存在三种模式:
--soft
: 仅修改快照指针, 本地缓存(stage)和工作区不受影响--mixed
: 修改快照指针, 同时将指向的快照版本放入本地缓存, 工作区不受影响.--hard
: 修改快照指针, 同时将快照放入工作区, 相当于checkout.
也可以通过git revert HEAD
指令进行回退.
Rebase 重建分支
在分支创建后, 如果主分支有新的提交, 可以将分支进行重建操作, 以使项目呈线性的提交历史.
在分支下执行指令git rebase master
即可.
rebase会修改项目的提交历史, 仅在本地, 不要在团队项目中使用.