git 内部工作原理图
如上图,git 一般可以分为三个区;工作区、暂存区、版本库,通常类似 git add等命令都是与index 暂存区的交互,git commit指令则是 index 与版本库的交互;将index区的内容 提交到版本库中;
1. mac使用git时常用的指令
ls -l -a 列出指定目录下文件
-l 显示文件的详细信息
-a 显示目录下所有文件(包括隐藏文件)
-d 显示指定目录pwd 显示当前的工作目录的路径 mkdir:创建新目录 pwd: 查看当前的路径 cat ss.txt :查看指定文本文件ss的内容(适合查看小文件) echo:输出字符串或变量值 列:echo "test">> ss.txt > 指定的文件若不存在,创建文件;若存在,覆盖原文件内容
输出重定向符
>> 指定的文件若不存在,创建文件;若存在,在原文件内容后追加内容 rm –rf * 强制删除当前目录下所有文件
rm -rf 删除文件或目录 stat 文件名 查看文件详细信息
find 查找文件
git 常用指令使用
1.git 基础指令
git init: git初始化生成 .git文件生成git仓库,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
git add 【file】: 添加文件到index 缓冲区;(git add添加到缓冲区后,在修改了文件,此时commit不会把修改的内容添加到仓库中,PS:每一次修改都必须重新添加到缓冲区之后commit才会生效)每次修改都必须add,然后才能commit;
git add -A // 添加所有改动
git add * // 添加新建文件和修改,但是不包括删除
git add . // 添加新建文件和修改,但是不包括删除
git add -u // 添加修改和删除,但是不包括新建文件
git commit -m "提交信息": 提交缓冲区到git仓库中; 注意这里仅仅是暂存区的内容 git status:查看git当前的状态(比如是否存在未添加和未提交的文件)
git status -s:简化查看状态 (M:红色代表本地修改, M:绿色已经提交到暂存区);
2.git log查看和操作记录查看
git log: 查看所有的git上传过的版本;
git log --pretty=oneline:查看所有的git上传过的版本 简化输出的信息;
git reflog: 查询记录git的每一次操作命令;
3.git 版本表示(以下指的均是版本库中的内容)
HEAD:当前版本;
HEAD^:上一个版本;
HEAD^^:上两个版本;
HEAD~100:前100个版本;
4.git 文件比较
git diff:查看当前的工作区所有文件与index暂存区中差别; git diff 【file】:查看具体文件与index暂存区中的差别;
git diff HEAD: 比较与版本库中的差别;
git diff HEAD -- 【file】:比较工作区和版本库中具体文件的差别;
5.git 文件删除
git rm [file] :同时删除工作区和暂存区的文件;如果需要删除版本库中的内容,还需git add . 添加 commit提交后才会生效 误删除后的还原操作:
1.还未执行git commit
提交到HEAD
的时候删除文件,这时候直接使用git checkout HEAD [file]
就能还原。(从版本库中拉取,覆盖)
2.执行git commit
提交到HAED
后时候删除文件,这时候就只能执行git reset --hard HEAD^
回退上一个版本。(版本回退)
6.git 撤销/回滚 操作
git checkout –- [file] 如果还未添加到暂存区,那么可以使用此命令 将暂存区的内容覆盖工作区的内容;此处必须制定文件名才行,否则不会生效!
git checkout HEAD [file] 与git reset --hard HEAD 一样,将版本库HEAD中的内容 同时替换暂存区和工作区的内容;
git reset HEAD 将版本库中的内容替换暂存区的内容,注意此时工作区不变; git reset --hard HEAD ,添加--hard 则暂存区和工作区内容都同时改变; git reset --hard commitId(提交版本哈希值);回退到commitId具体的版本中,同时覆盖暂存区和工作区; git revert HEAD 使用revert撤销上一次版本库中的内容;主要revert HEAD撤销的本质时 使用HEAD的代码库中的内容覆盖当前的修改的内容;然后做了一个新的commit提交;此时,旧版本commit历史记录还是存在的;只是多了一个新的提交;
7.git 分支合并
1.创建分支和切换分支 git checkout -b dev 我们创建dev分支,然后切换到dev分支: dev为分支的名字 等同于下面: git branch dev //创建dev分支 git checkout dev //切换到dev分支中 2.查看所有的分支情况 git branch (* 表示当前指针 指向了哪一个分支中!) 3.合并分支
3.1 首先切换主干分支
git checkout master
3.2 从分支dev中合并到主干master上
git merge dev
4.删除分支 git branch -d [分支名] 5.--no-ff 模式和 Fast forward模式 5.1 --no-ff 模式
git merge --no-ff -m "merge with no-ff" dev
因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。 包括了提交;命令; 5.2 Fast forward模式 快速模式(不添加参数情况) Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。
PS: --no-ff模式和 Fast forward模式的区别
1. --no-ff 模式
2.Fast forward模式
3.主要区别:
--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
6.分支策略
在实际开发中,我们应该按照几个基本原则进行分支管理:首先,master
分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev
分支上,也就是说,dev
分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev
分支合并到master
上,在master
分支发布1.0版本;
你和你的小伙伴们每个人都在dev
分支上干活,每个人都有自己的分支,时不时地往dev
分支上合并就可以了。
8.git stash 用法
git stash: 备份当前的工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时,将当前的工作区内容保存到Git栈中。
git stash pop: 从Git栈中读取最近一次保存的内容,恢复工作区的相关内容。由于可能存在多个Stash的内容,所以用栈来管理,pop会从最近的一个stash中读取内容并恢复。
git stash list: 显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。
git stash clear: 清空Git栈。此时使用gitg等图形化工具会发现,原来stash的哪些节点都消失了。
使用场景:
使用git的时候,我们往往使用branch解决任务切换问题,例如,我们往往会建一个自己的分支去修改和调试代码, 如果别人或者自己发现原有的分支上有个不得不修改的bug,我们往往会把完成一半的代码 commit提交到本地仓库,然后切换分支去修改bug,改好之后再切换回来。这样的话往往log上会有大量不必要的记录。其实如果我们不想提交完成一半或者不完善的代码,但是却不得不去修改一个紧急Bug,那么使用'git stash'就可以将你当前未提交到本地(和服务器)的代码推入到Git的栈中,这时候你的工作区间和上一次提交的内容是完全一样的,所以你可以放心的修 Bug,等到修完Bug,提交到服务器上后,再使用'git stash apply'将以前一半的工作应用回来。也许有的人会说,那我可不可以多次将未提交的代码压入到栈中?答案是可以的。当你多次使用'git stash'命令后,你的栈里将充满了未提交的代码,这时候你会对将哪个版本应用回来有些困惑,'git stash list'命令可以将当前的Git栈信息打印出来,你只需要将找到对应的版本号,例如使用'git stash apply stash@{1}'就可以将你指定版本号为stash@{1}的工作取出来,当你将所有的栈都应用回来的时候,可以使用'git stash clear'来将栈清空。 在这里顺便提下git format-patch -n , n是具体某个数字, 例如 'git format-patch -1' 这时便会根据log生成一个对应的补丁,如果 'git format-patch -2' 那么便会生成2个补丁,当然前提是你的log上有至少有两个记录。
git stash apply 和 git stash pop的区别
it stash 命令可以将在当前分支修改的内容放到缓存区中,并会自动建立一个缓存的list集合,方便管理。
如果想将修改的内容重新释放出来,git stash apply 和 git stash pop 都可以达到这个目的。
但是两者有什么区别呢。
刚才说过,git stash 可以形成list 集合。通过git stash list 可以看到list下的suoy
使用git stash apply @{x} ,可以将编号x的缓存释放出来,但是该缓存还存在于list中
而 git stash apply,会将当前分支的最后一次缓存的内容释放出来,但是刚才的记录还存在list中
而 git stash pop,也会将当前分支的最后一次缓存的内容释放出来,但是刚才的记录不存在list中 git stash 问题总结
1.如果在当前相同的分支上;在git stash后,如果当期的分支添加了新的内容并且与git stash时的版本产生了冲突时,(比如修改了同一处位置)
此时直接使用git stash pop时,并不会直接把原本保存的内容直接复制下来,而是会把更新的内容之后产生的冲突也会显示出来;
9.Git Patch功能
UNIX世界的软件开发大多都是协作式的,因此,Patch(补丁)是一个相当重要的东西,因为几乎所有的大型UNIX项目的普通贡献者,都是通过 Patch来提交代码的。作为最重要的开源项目之一,Linux,也是这样的。普通开发者从软件仓库clone下代码,然后写入代码,做一个Patch, 最后用E-mail发给Linux Kernel的维护者就好了。Git最初作为Linux的版本控制工具,提供了透明、完整、稳定的Patch功能。
我们先介绍一下Patch是什么。如果一个软件有了新版本,我们可以完整地下载新版本的代码进行编译安装。然而,像Linux Kernel这样的大型项目,代码即使压缩,也超过70MB,每次全新下载是有相当大的代价的。然而,每次更新变动的代码可能不超过1MB,因此,我们只 要能够有两个版本代码的diff的数据,应该就可以以极低的代价更新程序了。因此,Larry Wall开发了一个工具:patch。它可以根据一个diff文件进行版本更新。
不过在git中,我们没有必要直接使用diff和patch来做补丁,这样做既危险又麻烦。git提供了两种简单的patch方案。一是用git diff生成的标准patch,二是git format-patch生成的Git专用Patch。
1.git diff生成的标准patch
1.1 patch 生成;在更改文件以后,与master比较在当前的分支上生成patch
git diff master > patch
1.2 patch 应用;将生成的patch发送给别人,或者主干master上;
git apply patch
2.git format-patch生成的git专用补丁。
1.与主干master比较生成多个最近commit提交版本更改的patch
git format-patch -M master
如下图:生成最近更改的多个.patch文件
2. patch文件的应用
git am 0001-rm-patch.patch 应用某一个patch文件;
3.两种patch的比较:
- 兼容性:很明显,git diff生成的Patch兼容性强。如果你在修改的代码的官方版本库不是Git管理的版本库,那么你必须使用git diff生成的patch才能让你的代码被项目的维护人接受。
- 除错功能:对于git diff生成的patch,你可以用git apply --check 查看补丁是否能够干净顺利地应用到当前分支中;如果git format-patch 生成的补丁不能打到当前分支,git am会给出提示,并协助你完成打补丁工作,你也可以使用git am -3进行三方合并,详细的做法可以参考git手册或者《Progit》。从这一点上看,两者除错功能都很强。
版本库信息:由于git format-patch生成的补丁中含有这个补丁开发者的名字,因此在应用补丁时,这个名字会被记录进版本库,显然,这样做是恰当的。因此,目前使用Git的开源社区往往建议大家使用format-patch生成补丁。
10. Git .gitignore文件的用法
10.1 创建.gitignore 文件
windows:
创建一个文件,文件名为:“.gitignore.”,注意前后都有一个点。保存之后系统会自动重命名为“.gitignore”。
mac:
vim .gitignore 直接使用mac的终端命令即可;
注意 .gitignore是系统的隐藏文件 和 .git文件夹是一样的,看不到;在mac 中使用defaults write com.apple.finder AppleShowAllFiles -bool true 查看隐藏文件
10.2 编辑.gitignore 文件 在mac中如下:
编辑完成后,使用 git status,查看状态看看是否对于新增加的文件已经忽略;注意,对于已经加入版本库中的文件,此时在加入到.gitignore文件中无效的;只有刚加入,未添加进版本库中的文件 才会生效;
10.3 对于.gitignore 文件配置使用详解(转)
.gitignore文件过滤有两种模式,开放模式和保守模式
10.3.1 开放模式负责设置过滤哪些文件和文件夹
eg:
过滤文件夹设置:
/mtk/
过滤文件设置
指定过滤某种类型的文件:
*.zip
*.rar
*.via
*.tmp
*.err
指定过滤某个文件:
/mtk/do.c /mtk/if.h
2.2 b保守模式负责设置哪些文件不被过滤,也就是哪些文件要被跟踪。
跟踪某个文件夹
!/plutommi/mmi
跟踪某类文件
!*.c !*.h
跟踪某个指定文件
!/plutommi/mmi/mmi_features.h
3.配置.gitignore 的简易原则
采用共享模式与保守模式结合配置的办法。eg:一个文件夹下有很多文件夹和文件,而我只想跟踪其中的一个文件,这样设置就可以满足这种情况,先用共享模式把整个目录 都设置为不跟踪,然后再用保守模式把这个文件夹中想要跟踪的文件设置为被跟踪,配置很简单,就可以跟踪想要跟踪的文件。