5. Git补充资料
自动补全
在输入 Git 命令的时候可以敲两次跳格键(Tab),就会看到列出所有匹配的可用命令建议
设置alias
$ git config alias.shortname <fullcommand>
让Git显示颜色,会让命令输出看起来更醒目:
$ git config --global color.ui true
.gitignore详解
在Git工作区的根目录下创建一个特殊的.gitignore
文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
不需要从头写.gitignore
文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可浏览:https://github.com/github/gitignore
注意:.gitignore
文件本身要放到版本库里,并且可以对.gitignore做版本管理!
- 所有空行或者以注释符号 # 开头的行都会被 Git 忽略。
- 可以使用标准的 glob 模式匹配。
- 匹配模式最后跟反斜杠(/)说明要忽略的是目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
所谓的 glob
模式是指 shell
所使用的简化了的正则表达式。
- 星号(*)匹配零个或多个任意字符;
- [abc] 匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);
- 问号(?)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)。
我们再看一个.gitignore
文件的例子:
# (相对)忽略 build/ 相对目录下的所有build目录, 不忽略build文件
build/
# (相对)会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
doc/*.txt
# (相对)忽略所有 .log 结尾的文件
*.log
# 但 pref.log 除外
!pref.log
# (绝对)仅忽略*项目根*目录下的 TODO 文件和目录
/TODO
以下是说明:
# 忽略something文件和something目录
something
# 只忽略something目录,不忽略something文件
something/
# 只忽略something文件,不忽略something目录
something
!something/
# 只忽略当前目录下的something文件和目录,子目录的something不在忽略范围内
/something
# 总结: 一般用第二种'something/'就够了
示例: gitignore/Java.gitignore
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
用git check-ignore命令检查规则:
$ git check-ignore -v App.class
.gitignore:3:*.class App.class
Git会告诉我们,.gitignore
的第3行规则忽略了该文件,于是我们就可以知道应该修订哪个规则。
分支开发策略
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
分支的衍合
衍合是按照每行的修改次序重演一遍修改,而合并是把最终结果合在一起。
$ git checkout experiment
$ git rebase master
它的原理是回到两个分支最近的共同祖先,根据当前分支(也就是要进行衍合的分支 experiment)后续的历次提交对象(这里只有一个 C3),生成一系列文件补丁,然后以基底分支(也就是主干分支 master)最后一个提交对象(C4)为新的出发点,逐个应用之前准备好的补丁文件,最后会生成一个新的合并提交对象(C3'),从而改写 experiment 的提交历史,使它成为 master 分支的直接下游,如图 3-29 所示:
一般我们使用衍合的目的,是想要得到一个能在远程分支上干净应用的补丁 — 比如某些项目你不是维护者,但想帮点忙的话,最好用衍合:先在自己的一个分支里进行开发,当准备向主项目提交补丁的时候,根据最新的 origin/master 进行一次衍合操作然后再提交,这样维护者就不需要做任何整合工作(译注:实际上是把解决分支补丁同最新主干代码之间冲突的责任,化转为由提交补丁的人来解决。),只需根据你提供的仓库地址作一次快进合并,或者直接采纳你提交的补丁。
git rebase [主分支] [特性分支] 命令会先取出特性分支 server,然后在主分支 master 上重演。
当前分支可以git rebase [主分支] , 省略了当前特性分支而已。
衍合的风险
呃,奇妙的衍合也并非完美无缺,要用它得遵守一条准则:
一旦分支中的提交对象发布到公共仓库,就千万不要对该分支进行衍合操作。
如果把衍合当成一种在推送之前清理提交历史的手段,而且仅仅衍合那些尚未公开的提交对象,就没问题。如果衍合那些已经公开的提交对象,并且已经有人基于这些提交对象开展了后续开发工作的话,就会出现叫人沮丧的麻烦。
自定义git
让Git显示颜色,会让命令输出看起来更醒目:$ git config --global color.ui true
stash储藏的用法
当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug
git stash save 'comme'
//这样stash会有注释
Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
-
git stash apply
s恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除; - 另一种方式是用
git stash pop
,恢复的同时把stash内容也删了:
恢复指定的stash, 只需要指定序号, {0}代表最新的stash
$ git stash apply stash@{0}
$ git stash apply stash@{1}
...
# %d代表数字
$ git stash apply stash@{%d}
bash常用命令
$ cd /d/k_git(正确)
进入对应的目录
$ mv [old-name] [new-name]
重命名
$ rm test.txt
删除当前目录下的一个文件
$ mkdir [folder-name]
当前目录下建立文件夹
$ pwd
显示当前目录
$ ls -al
查看该目录下的文件和文件夹
$ ls -ah
查看该目录下的文件和文件夹包含隐藏目录
疑难
Git pull失败
refusing to merge unrelated histories
解决方案:添加--allow-unrelated-histories
$git merge origin/master --allow-unrelated-histories
Git中的AutoCRLF换行符问题
建议把autocrlf设置为false,并且把所有文件转换为Linux编码(即LF\n)
#提交检出均不转换
$ git config --global core.autocrlf false`
这是三种取值true, input, false的解释