Git学习笔记
前言:虽然学习git没几天,对git的理解也不够全面,但是还是写点笔记,记录一下掉坑爬坑的过程。
------------------------------------------------------------------------------------------------------------
环境:win7 x64 、Git2.11.0 for windows
需求:上传Android4.0.3系统源码至github托管,供自己阅读及学习Android系统使用
注意事项:github上每个仓库最大容量为1GB,单个文件最大容量为100MB,还有git对文件名的大小写不敏感for windows
------------------------------------------------------------------------------------------------------------
1.搭建环境
1.1 安装git:https://git-for-windows.github.io/
1.2 在github中新建一个仓库,比如Android4.0
1.3 建立与github的连接
ssh-keygen -t rsa -C "youremail"
生成一个key,这个key用来与你的github进行连接,不然服务器怎么知道你是谁,是吧,之后会要求确认路径和输入密码,我们这使用默认的一路回车就行。成功的话会在C:\Users\Administrator\.ssh目录下生成一个key,保存在id_rsa.pub文件中,复制里面的key,再回到github,进入Account Settings,选择SSH Keys,Add SSH Key,title随便填一个,粘贴key,搞定。
1.4 为了验证是否成功,在git bash下输入:
ssh -T git@github.com
如果是第一次的会提示是否continue,输入yes之后,如果出现:You’ve successfully authenticated, but GitHub does not provide shell access 。这就表示已成功连上github,否则看看哪一步错了,再折腾一次就好了。
1.5 配置你的用户名与邮箱,这是每次你提交代码的时候会有记录是谁谁谁提交的
git config --global user.name "yourname"
git config --global user.email "youremail"
1.6 为了防止没有任何操作而中断与服务器的连接,我们让服务器给客户端发送心跳包保持长连接
在git安装目录下的etc/ssh/ssh_config配置文件增加如下参数
Host * ServerAliveInterval 60
2.初始化git
2.1 进入到需要托管的本地文件夹,比如Android4.0.3
2.2 右键进入Git Bash Here选项,打开命令窗口,现在,开始我们的git之旅啦
2.3 新建一个本地仓库
git init
新建一个.git文件夹,作为本地仓库的管理
2.4 添加远程地址,表明该项目要上传到github的哪个仓库里
git remote add origin git@github.com:yourName/yourRepo.git
yourName和yourRepo表示你在github的用户名和新建的仓库,加完之后进入.git,打开config,这里会多出一个remote “origin”内容,这就是刚才添加的远程地址,也可以直接修改config来配置远程地址。
好啦,初始化git完成啦,接下来我们来添加,提交操作吧
3.git主要命令
3.1 首先我们需要添加代码到暂存区
git add -A
表示添加当前目录下所有未加入版本控制以及已更改的文件,也可以指定文件或文件夹
3.1.1 如果我发现add错了,不想add了,使用
git rm --cache
这里也可以指定文件或文件夹,默认会撤销所有暂存区的文件
3.2 提交到本地仓库
git commit -m "yourLog"
表示把你添加的代码文件提交到本地的仓库中,若需要换行,则把“换成‘即可,例
git commit -m ' 1.aaa 2.bbb '
3.2.1 如果我发现commit错了,我需要恢复原来的仓库,使用
git reset --hard 版本号
可以恢复上一个版本的仓库
3.3 推送到远程仓库即github中
git push origin master
origin表示版本库名即我们remote add的origin,master表示分支名,分支的用法很值得深究
3.3.1 如果我要删除远程仓库的文件,我可以使用rm删除暂存区的文件,然后commit到本地仓库最后push到远程仓库中
第二种方式,直接在github上手动删除该文件,但是这需要我们在本地使用git pull同步一下本地仓库,否则push会失败哦
3.3.2 如果我要恢复远程仓库的文件,也就是说我误删了远程仓库的文件怎么办,不要着急,我们只要把本地仓库回溯一下,恢复到我们希望的版本,然后push到远程就ok了
3.4 从远程仓库下载文件到本地
git pull origin master
或
git fetch origin master
git pull会下载到本地仓库并合并分支,而git fetch不会主动合并分支,就比如说我本地文件已经修改,而我也没有commit,但我又不想丢弃我的本地修改,那么肯定就不希望合并,而使用pull会主动去merge
3.5 下载github上的项目
git clone https://github.com/hisName/hisRepot.git
3.6 查看当前的状态,即有没有add呀,add了哪些呀,更改了哪些文件呀等等
git status
3.7 查看本地仓库与工作区的更改内容
git diff
3.8 忽略特定格式的文件
在仓库根目录下创建名称为“.gitignore”的文件,向其中添加不需要上传的文件夹与文件,例如不想传out目录bin目录以及后缀为bin的文件
out
bin
*.bin
一个文件占一行就好
好啦,是不是有点晕,哈哈那就解释一下git的工作区域,这里有四个概念,
1.工作区,就是我们本地文件夹,我们现在能看得到的文件
2.暂存区,当我们执行add命令后,add的文件会保存至暂存区
3.本地仓库,当我们执行commit命令后,先前add的文件会提交到本地仓库中
4.远程仓库,当我们执行push命令后,才会把本地仓库同步到远程仓库中,否则远程仓库是不会有变动的。
以上是我个人对git的理解,如有错误,还望指出,本人不甚感激。
更多git命令就看大神的博客:http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
----------------------------------------------------------------------------------------------------------------------------------------
好啦,接下来是吐槽时间!!!!!!!!!!!!!!!!!!!
怎么说呢,我的需求是上传Android源码到github上,最开始什么也没考虑,就是干,Android4.0整个源码不加二进制文件就有20w+个,一次性上传那得传到啥时候去啊,果断选择分文件夹上传,传了一天,突然想起这服务器总有个容量吧,遂网上一查,嘿,还真有,一个仓库最大1GB,如果真要全上传那再开几个仓库就好了嘛,后来又传了一天,还剩下一半源码,为何这么慢,网络啊!都是泪,唉,后来想想算了,反正改的最多的也就是Frameworks了,那把这个文件夹上传上去好了,这里放上github链接:https://github.com/pngcui/Android4.0_Frameworks
接着上传kernel的源码,这下子有意思的来了,注意:前方高能
想着整个kernel3.0也就500MB,4w多个文件,那干脆全传上去好了,毕竟以后在kernel上改动的也比较大
当我在上传include文件夹的时候,add报错了
error: short read: No such file or directory error: include/linux/netfilter_ipv6/ip6t_HL.h: failed to insert into database error: unable to index file include/linux/netfilter_ipv6/ip6t_HL.h fatal: adding files failed
include/linux/netfilter_ipv6/ip6t_HL.h No such file ???去找找有没有该file,哦,能see能vi也能保存,我不信邪,执行以下命令
git add include/linux/netfilter_ipv6/ip6t_HL.h 好吧,依旧报如上错误,什么鬼啊,不是有这个文件吗,你傻逼啊,
注意:我在该目录下发现存在一个ip6t_HL.h以及一个ip6t_hl.h的文件,嗯,就是文件名部分大小写不一样,可是这应该不会是问题所在吧!!既然把文件添加至缓存,怎么可能大小写不敏感呢
好吧,那我改下名吧,改为ipt6t_HL01.h,继续add .......................然后add成功了,我.......................整个人都惊呆了,这一定不是事实,我不信!!
好吧,还是不得不接受这个残忍的事实啊...那就继续add吧,先把源码传上去,再在github上把文件名改回来好了,接下来还有6个文件一样的err,改了继续
ok上传到github了,嗯,一个个改名,有图为证,还好github提供在线编辑的功能
前面我们也提到了,如果我们在github上改动了仓库,那么需要在本地执行git pull同步一下对吧
ok,执行git pull origin master
$ git pull origin master remote: Counting objects: 35, done. remote: Compressing objects: 100% (35/35), done. remote: Total 35 (delta 28), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (35/35), done. From github.com:pngcui/Android4.0_linux3.0 * branch master -> FETCH_HEAD 00f8d8f5..96bd42f1 master -> origin/master Updating 00f8d8f5..96bd42f1 Fast-forward include/linux/netfilter/{xt_CONNMARK01.h => xt_CONNMARK.h} | 0 include/linux/netfilter/{xt_DSCP01.h => xt_DSCP.h} | 0 include/linux/netfilter/{xt_MARK01.h => xt_MARK.h} | 0 include/linux/netfilter/{xt_RATEEST01.h => xt_RATEEST.h} | 0 include/linux/netfilter/{xt_TCPMSS01.h => xt_TCPMSS.h} | 0 include/linux/netfilter_ipv4/{ipt_TTL01.h => ipt_TTL.h} | 0 include/linux/netfilter_ipv6/{ip6t_HL01.h => ip6t_HL.h} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename include/linux/netfilter/{xt_CONNMARK01.h => xt_CONNMARK.h} (100%) rename include/linux/netfilter/{xt_DSCP01.h => xt_DSCP.h} (100%) rename include/linux/netfilter/{xt_MARK01.h => xt_MARK.h} (100%) rename include/linux/netfilter/{xt_RATEEST01.h => xt_RATEEST.h} (100%) rename include/linux/netfilter/{xt_TCPMSS01.h => xt_TCPMSS.h} (100%) rename include/linux/netfilter_ipv4/{ipt_TTL01.h => ipt_TTL.h} (100%) rename include/linux/netfilter_ipv6/{ip6t_HL01.h => ip6t_HL.h} (100%)
OK~把我原先改过文件名的文件都改回来了,为了证实,打开目录include\linux\netfilter,昂?????xt_connmark.h呢???excuse me???!,
那么,我再使用git diff看看
$ git diff diff --git a/include/linux/netfilter/xt_connmark.h b/include/linux/netfilter/xt_connmark.h index efc17a83..2f2e48ec 100644 --- a/include/linux/netfilter/xt_connmark.h +++ b/include/linux/netfilter/xt_connmark.h @@ -1,31 +1,6 @@ -#ifndef _XT_CONNMARK_H -#define _XT_CONNMARK_H +#ifndef _XT_CONNMARK_H_target +#define _XT_CONNMARK_H_target -#include <linux/types.h> +#include <linux/netfilter/xt_connmark.h> -/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> - * by Henrik Nordstrom <hno@marasystems.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */
啊??xt_connmark.h有差别??我一万个黑人问号。。。
于是我悄悄的打开了xt_CONNMARK.h与xt_connmark.h两个文件
xt_CONNMARK.h内容如下:
#ifndef _XT_CONNMARK_H_target #define _XT_CONNMARK_H_target #include <linux/netfilter/xt_connmark.h> #endif /*_XT_CONNMARK_H_target*/
xt_connmark.h部分内容如下:
#ifndef _XT_CONNMARK_H #define _XT_CONNMARK_H #include <linux/types.h> /* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> * by Henrik Nordstrom <hno@marasystems.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ enum { XT_CONNMARK_SET = 0, XT_CONNMARK_SAVE, XT_CONNMARK_RESTORE }; ...
很明显xt_CONNMARK.h与xt_connmark.h这两个文件名都不一样,而git diff是把本地工作区与本地仓库的文件进行对比啊
但是我本地就没有xt_connmark.h这个文件好吧,git你怎么能用xt_CONNMARK.h冒充xt_connmark.h来骗我呢???
难道git真的大小写不敏感???????!!!!!!!!!!!!!!!!!!!!!!!
网上一查,我去类,果然git默认是大小写不敏感,这不坑人吗,真是在这个坑摔个狗吃屎(/ □ \)
可以使用命令设置git大小写敏感,它只更改.git/config配置,即每个项目都需要执行一次!
windows系统对文件名大小写不敏感!在Linux下不会,所以最好还是在Linux环境下进行源码的提交等
git config core.ignorecase false
如果碰到这样的情况,请把两份文件都git rm --cached(只删除暂存区的,不删除本地工作区的文件),commit,然后push到远程
然后继续add,commit,push,这样就不会出错啦!
好了,说了这么多,我继续传源码去了,最后附上几个详细的教程
配置git上传到github上的详细流程:http://blog.csdn.net/luckyyulin/article/details/21090905
撤销git的操作:http://www.tuicool.com/articles/BJfUn2B
为什么git要先add然后commit:https://www.zhihu.com/question/19946553
git与svn的区别:http://blog.csdn.net/ithomer/article/details/7529022#comments
作者:pngcui
博客园:http://www.cnblogs.com/pngcui/
github:https://github.com/pngcui
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明。