git将所有文件分成三类:已追踪的、被忽略的以及未追踪的。
可以在gitignore中配置忽略文件,其格式如下:
由于gitignore文件可以在很多地方配置,因此其有优先级,优先级由高到低如下:
一般开发中,都会在代码库的工作区跟目录指定.gitignore文件
对于有些网络不通获取其他情况,需要使用补丁来合并代码。git提供了三个特定命令来帮助交换补丁
format-patch命令会以邮件消息的形式生成一个补丁,每个提交都是一个相对于上个提交的补丁文件。用法如下:
git format-patch -2 -------------最近的两次提交,生成两个补丁文件
git format-patch master~4..master~2 -----特定的范围
补丁文件生成好以后需要发送补丁文件,你可以直接通过个人邮箱以附件的形式发送,不过git提供了send-email命令来直接发送补丁文件。例如:
git send-email -to my@example.com 0001-A.patch
但是你需要配置你的邮箱的SMTP服务器的地址和端口号才行:
git config --global sendemail.smtpserver smtp.my-isp.com
git config --global sendemail.smtpserverport 465
可以通过查询邮箱的smtp服务器来配置,一般在邮箱的设置选项里面可以看到smtp服务器地址,例如网易的免费邮如下:
邮箱 | POP3 服务器(端口110) | SMTP 服务器(端口25) |
---|---|---|
188.com | pop3.188.com | smtp.188.com |
163.com | pop3.163.com | smtp.163.com |
126.com | pop3.126.com | smtp.126.com |
netease.com | pop.netease.com | smtp.netease.com |
yeah.net | pop.yeah.net | smtp.yeah.net |
可以使用git am命令来应用补丁,
git am /temp/0001-B.patch
当git出现版本库如提交或者推送事件的时候,会触发钩子(特定的脚本),钩子中可以处理其他的一些事情,例如触发CI构建,或者决定事件是否有效,例如提交的日志不符合一定的格式,不能提交。
git的钩子只属于特定的版本库,在clone操作的时候并不能复制。也就是每个开发人员都需要设置通过复制文件的形式把钩子脚本copy到.git/hooks目录
一般钩子分成两种:
在.git/hooks目录下,预制了很多钩子样例文件,直接把相应文件的.sample后缀去除就是一个钩子文件。提交钩子的流程如下:
pre-commit hook -----------------可以使用--no-verify屏蔽,这个钩子脚本调用的时候没有入参,因此只能通过git diff --cache命令来获得提交的内容,然后进行判断
|
V
commit-msg hook -------------可以使用--no-verify屏蔽,这个钩子脚本只有一个参数,即.git/COMMIT_EDITMSG文件的路径位置。用户可以通过读取这个文件来对提交的日志进行一些校验
|
V
actully do the commit
|
V
post-commit hook --------------没有入参
可以使用git help hooks命令来查看当前版本支持的钩子。
通过git 的对象可以知道,每次提交存储的都是一个完整的内容,而不是和上次提交的差异。这样如果对应比较大的文件,而每次提交对该文件做了小小的改动,会导致对象库里面存储效率很低。
为了解决这种存储效率低的问题,git提供了一种打包文件,git首先定位内容非常相似的全部文件,然后为他们之一存储整个文件内容,之后计算相似文件之间的差异并且只存储差异。
打包文件在.git\objects\pack目录下面。
git对象库中可能存在大量的未引用的文件,例如git reset命令、git filter-branch命令。如果版本库中有很多的松散对象,执行git reflog expire命令是,都会触发git gc或者手动触发gc命令,那么就会清理对象库中的文件
filter-branch命令是一个比较重量级的命令,可以通过自定义的命令来利用它操作不同的git对象,从而重写分支上的提交。
其具体应用如下:
1、修改author和committer,当我们想把代码库公开的时候,但是想替换每个提交的作者和邮箱地址,那么可以使用如下的命令:
$ git filter-branch --commit-filter ‘
if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
then
GIT_AUTHOR_NAME="Scott Chacon";
GIT_AUTHOR_EMAIL="schacon@example.com";
git commit-tree "$@";
else
git commit-tree "$@";
fi‘ HEAD
2、每一个提交移除一个文件
这经常发生。 有人粗心地通过 git add . 提交了一个巨大的二进制文件,你想要从所有地方删除它。 可能偶然地提交了一个包括一个密码的文件,然而你想要开源项目。 filter-branch 是一个可能会用来擦洗整个提交历史的工具。 为了从整个提交历史中移除一个叫做 passwords.txt 的文件,可以使用 --tree-filter 选项给 filter-branch:
$ git filter-branch --tree-filter ‘rm -f passwords.txt‘ HEAD
Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21)
Ref ‘refs/heads/master‘ was rewritten
--tree-filter 选项在检出项目的每一个提交后运行指定的命令然后重新提交结果。 在本例中,你从每一个快照中移除了一个叫作 passwords.txt 的文件,无论它是否存在。 如果想要移除所有偶然提交的编辑器备份文件,可以运行类似 git filter-branch --tree-filter ‘rm -f *~‘ HEAD 的命令。
最后将可以看到 Git 重写树与提交然后移动分支指针。 通常一个好的想法是在一个测试分支中做这件事,然后当你决定最终结果是真正想要的,可以硬重置 master 分支。 为了让 filter-branch 在所有分支上运行,可以给命令传递 --all 选项。
对于代码库合并可以使用如下的步骤:
1、git remote add anoterURL ------------使用git remote命令添加其他仓库的url
2、git pull anoternURL --allow-unrelated-histories ------------使用git pull命令拉取其他仓库的代码,注意要使用--allow-unrelated-histories
而如果需要把其他的代码库检查到当前代码库的某个子目录,需要使用协同模型---子树合并的方式,请参考后续的博客。
在windows下经常使用git clone命令或者checkout命令的时候,由于需要检查的代码路径超过了256导致失败,这时可以增加core.longpaths配置来解决。例如:
git config core.longpaths true
如果该配置设置以后仍然不能生效,那么需要检查一下你的git版本是否过低,把git升级到新版本就可以了,因为这个参数配置也是需要git高版本才能生效。
原文:http://blog.51cto.com/5162886/2091385