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%Cresetgit 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.0git 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会修改项目的提交历史, 仅在本地, 不要在团队项目中使用.






