已经开始使用Git了,有些时候一般的问题只能Google就能找到答案,但是有些时候不能找到答案,因为遇到的问题都不知道该用什么关键字搜索。很多是在Git中文的QQ群中讨论出来的,把一些经验总结一下:
1.Git子模块
使用情况:例如Android系统代码和app之间可以使用这种submodule的方法来管理。
快速上手:
$ git submodule add url path/to/name $ git submodule init $ git submodule foreach git pull |
其它情况下submodule不适用,可以用subtree来代替。
2.同步一个COMMIT
可以同步一个commit到本分支
3.Git打TAG
打TAG也就是发布版本
$ git tag -a v1.2 -m "version 1.4" $ git push --tags |
如果还不能理解可以到这里看看是linus是怎么给linux内核打的TAG,TAG看起来像什么:https://github.com/torvalds/linux/releases
4.查看status详情
$ git add xxx $ git diff --cached |
这样可以在commit之前先看一下修改详情。
5.不产生无用的merge的同步
有这么一种情况,用一个分支专门同步代码提供商的代码的时候,如果一般的pull会不断的产生一个merge看起来会很烦,用下边的使用添加一个--rebase就不会产生无用的merge了
$ git pull --rebase origin master |
6.关于stash
适用情况:做了修改后,还没有add commit等等后续工作,现在突然要切换分支做其它事情,默认情况下你在这个分支修改的代码会被带到切换过去的分支中。可以先把你修改的保存起来。这些修改可以再还原过来。
$ git stash -u $ xxxx 随便你的操作 $ git stash pop |
注意:-u是代表是也把添加的新文件(术语是未跟踪)也藏起来,一般是要有这个u的。
7.恢复一个COMMIT
如果一个COMMIT你不想要了,想要去除,可以考虑使用以下的方法;
这个就可以去掉这个COMMIT的改动,这个是明式的去掉,如果你又后悔了,还可以再次恢复。
8.安装最新Git版本
能轻易安装的一般不会是最新的,用apt-get install便是如此。下面用离线的方式安装Git。
a先到https://github.com/git/git/releases看最新版本,然后复制链接。红色随具体版本变化。
$ apt-get remove git # 卸载现有 $ wget https://github.com/git/git/releases/tag/v1.8.4.3 (链接地址) $ tar xvzf v1.8.4.3.tar.gz $ cd git-v1.8.4.3 $ make prefix=/opt/git all $ make prefix=/opt/git install $ 添加/opt/git/bin到环境变量中 /etc/environment中,或者其它。 |
9.安装subtree
$ git clone https://github.com/apenwarr/git-subtree $ cp git-subtree/git-subtree.sh /opt/git/bin/git-subtree |
关于使用的subtree的几个帖子:
《使用git subtree集成项目到子目录》
《一个成功的Git分支模型》
10.Git之本地忽略
这个分同种情况:a是本地永久忽略,效果的gitignore一样,只不过不适于写到gitignore中而已,可以自己建立一个本地独享的gitignore,然后git
config --global core.excludesfile 文件的绝对路径,也可以直接将本地要忽略的文件添加到.git/info/exclude中。不过上述都是针对没有跟踪的文件来说的,如果文件已经被跟踪了你如果在本地想要忽略它的改动,就不能使用以上的方法了。这正情况b。通俗地讲比如一个编译Android的脚本在其它电脑上都是使用的-j32来编译的,但是你的电脑配置没有别人的好,不能开到-j32,但是这个脚本是已经跟踪过的,你修改了就会在每次的git
status中看到。对于这种情况Git有一个忽略改动的方法:
$ git update-index --assume-unchanged /path/to/file #忽略跟踪 $ git update-index --no-assume-unchanged /path/to/file #恢复跟踪 |
之后你在本地修改/path/to/file这个文件,Git也不管它了。就实现了本地忽略。
11.Gitlab用户头像的问题
如果装的Git服务器是GitLab的话,是可以使用用户头像的,GitLab管理头像的一般方法是用gravatar,这一点和github一样,是关联email地址的,先在上边注册一个账户,上传一个头像并关联某一个邮箱,Gitlab或者Github会自动去gravatar上拉取你的个人头像。
12.Git打包源码
对Git管理的源码进行压缩打包,如果使用tar xvzf xxxx.tag.gz xxxxx的话并不是一个很好的选择,因为会将.git/目录下的中间文件全部压缩,如果只想要某一个版本的源码。Git提供了archive.它会给打包一份纯净的代码。当然这个只适用于发部一个版本的源码,而不是备份Git管理的整套源码。
xxx代表SHA-1 Hash值。
13.Git反向打补丁
一套没有管理有源码,中间有功能A,且也有功能A的补丁文件,可以使用补丁文件进行反打补丁来实现去掉功能A。
注:只是收集,还没有完整测试这里。
14.关于Git服务器选择和安装
选择建议GitLab,安装我参考加总结这几个帖子:
1.《 gitlabhq / doc / install / installation.md 》根据国情为官方的安装方法添加了说明的安装文档。
2.《 在 Ubuntu 12.04 上安装 GitLab6.x》一个对安装过程打印信息都记录的安装文档,安装过程中可以对比安装过程。
3.《重设MySQL root密码》中间遇到的问题MySQL密码找不到了,这篇文章给了答案。
15.合并commit
1.《使用git合并多个提交》
2.《git如何合并只有两个commit到一个?》
16.Git只clone最新版本代码不要.git目录
这个也是在群中出现了问题,我曾经也有过这样的需求,想法是好的,但是理解是错误的。如果只要最后一个版本的代码,而不要.git目录中的东西,有办法:
git clone --depth=1 git://someserver/somerepo dirformynewrepo
rm -rf !$/.git |
但是这又说明不是要参与开发的,是使用的。使用一般是要使用代码开发最新发布版本,如果只要最新的提交版本是没有用处的。因为它不是稳定的。这样就引入了发布版本这一说明,Git中是打Tag,一个tag是一个版本,可以以刚才的需求去找最后一个tag版本。github上是可以直接下载某一个tag版本的。如果要用git
clone来完成,会复杂一些。现在的github是结合了web的,例如github或者是自己搭建的gitlab都是可以直接从web上下载指定的tag版本。而没有用于版本控制的.git目录。
17.关于pull和merge
都在提倡添加--no-ff选项。
18.删除子模块-解决子模块自动找上门的问题
也许你并不想要用子模块,但是有时它会自动找上门,那么你要了解一下怎么去除它了。怎么个自动上门,且听我慢慢道来。
在项目A中,如果用git clone了另外一个项目B,或许你只是想把项目B的代码添加到项目A中,但是这时执行git
status/add的时候会发现项目B中的代码,并不会被添加,也就是说不能被跟踪。这是为什么呢,这里因为会自动将项目B做为了子模块管理,就是因为它是一个包含.git目录的完整的工程。解决这个问题有同种方法:
1.在clone项目b的后立即将项目B中的.git目录删除
2.git rm --cached path/to/B
然后再执行git status/add 之类的命令就会可以正常的跟踪了。
19.恢复一个文件到之前的某个提交
这个种情况一般是出在某个bug解决后整理规范代码的时候,解决这个bug的时候可能添加了不少的调试代码,最后解决后,有些调试信息只为了了解代码流程,对以后并没有保留的意义,所以就要将其恢复开始解决这个bug之前的提交。xxxxx代表开始解决这个bug之前的一个提交的哈希码。
对于已经跟踪的文件:
1.git reset xxxxxx path/to/file
2.git checkout path/to/file
对于没有跟踪的文件:
1.git rm path/to/file
20.合并时只产生合并提交
还有其它说法:合并时不合并历史;合并时将所有commit合为一个。
git pull --squash another
话说一般用于master分支,像linus的linux内核一样。
更多信息见《Git merge no history commit》《git merge –squash介绍》
21.关于GUI Clients
这里《GUI Clients》。
22.git pull 前简单审查
情况是这样的:本人管理的是develop分支,其他人管理的他们自己的分支。所以应该每次改动的都应该是package/apps下的文件,但是有一种情况是我担心他们会不小心改到系统代码并提交了。在合并之前查看都改了哪些文件。这样就能有效地防止误修改。
和老友沟通后,得出以下结论:
1.让他们添加本地忽略,忽略他们一定不会改的目录。
2.在每次合并代码的时候,看一下每个分支都修改了哪些文件,有没有系统文件被修改。
3.使用grrit。
4.先git fetch 再merge。
最后选择了第二种。因为git pull后,提交的时候会显示出这次合并代码都有哪些修改。
23.Gitk 不错的查看Log的工具
24.Git遇上代码规范
当Git遇上代码规范会有些事情要处理好,这里写先写个经典的:
1.检测自己要提交的代码中有无table
一般多人开发的程序中不准使用table代替空格的,以下是Google的Java代码规范(中文)中的截图:
所以在提交代码前自检一下自己代码中有有无table是很有必要的。
$ git diff | grep -P “\t” | grep “+” |
如果tab已经存在,这里有很好的解决方案,所以项目代码不要急于commit前期工作很重要。
25.You are in the middle of an am session.
$ git status On branch hardware You are in the middle of an am session. (fix conflicts and then run "git am --continue") (use "git am --skip" to skip this patch) (use "git am --abort" to restore the original branch) nothing to commit, working directory clean $ |
对于这个情况,我是在接手一个别人的仓库的时候遇到的,我目前没有更好的方法,也不知道做了哪些事情,我采取的是
重新clone一份代码。 |