一. git常用指令说明
- 初始化一个仓库
git init
git add readme.md // git add 添加一个文件到 暂存区;
- git commit 命令用于把暂存区域的文件提交到 Git 仓库
git commit -m “readme.md commit” // "readme.md commit"是提交的注释
-
git status // 查看文件状态
-
git log // 查看历史记录 获取全部版本号,此命令不包含回退的立式记录
git log --pretty=oneline // 版本号 和提交的注释 一行显示
git reflog // 查看历史记录,获取前7位版本号,此命令包含回退的历史记录
git log --follow -p user/nsh.c 查看某个文件的历史记录
- 版本回退:
git reset 命令用于把 Git 仓库的文件还原到暂存区域
git reset --hard^ // 一个^号表示回退上一个版本
git reset --hard^^ // 一个^号表示回退上一个版本,两个表示回退至前两个版本
git reset --hard~100 // 回退至前100个版本
git reset --hard 版本号
git reset head~ // 取消上一次的提交
reset回滚快照
git reset --soft (版本号/快照) //只是将仓库的快照回滚
git reset --mixed (版本号/快照) //将仓库快照回滚,并将文件回滚至暂存区
git reset --hard (版本号/快照) //将仓库快照回滚,并将文件回滚至工作区
git checkout (文件) 命令用于把 暂存区域的文件or历史快照(git仓库) 还原到 工作目录
- diff
git diff readme.md // 比较文件有什么不同 谁和谁比较?
比较暂存区域与工作目录的文件
// git diff指令详解
$ git diff
//表示对比的是暂存区域和工作路径的readme.md
diff --git a/readme.md b/readme.md
//表示对应文件的ID分别是86c39c9 和26c0571,这个文件ID怎么查?
// 100644是指定文件的类型和权限
index 86c39c9..26c0571 100644
// ---表示该文件是旧文件 存放再暂存区域
--- a/readme.md
// +++ 表示该文件是新文件 存放在工作路径
+++ b/readme.md
// 以 @@ 开头和结束,中间的“-”表示旧文件,“+”表示新文件,后边的数字表示“开始行号,显示行数”
@@ -1,3 +1,4 @@
this is a big project~
this line will not commited success!
-today is a good day 20190412~
\ No newline at end of file
+today become bad days, because I waste too much time on
+smart phone~
// linux的文件 权限说明
The following flags are defined for the st_mode field:
S_IFMT 0170000 bit mask for the file type bit fields
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
S_ISUID 0004000 set UID bit
S_ISGID 0002000 set-group-ID bit (see below)
S_ISVTX 0001000 sticky bit (see below)
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
- 重命名文件:
git mv game.py wordgame.py //重命名仓库端的game.py
- gitignore 语法规范
用途:如果想提交的时候忽略某种类型的文件,可以将它放在./gitignore下
.gitignore 可以使用标准的 glob 模式匹配(glob 模式是指 shell 所使用的简化了的正则表达式):
所有空行或者以注释符号 # 开头的行都会被 Git 忽略;
- 星号(*)匹配零个或多个任意字符;
- [abc] 匹配任何一个列在方括号中的字符;
- 问号(?)只匹配一个任意字符;
- [a-z] 匹配所有在这两个字符范围内的字符;
- 匹配模式最后跟反斜杠(/)说明要忽略的是目录;
- 匹配模式以反斜杠(/)开头说明防止递归;
- 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
- 分支
git 创建分支
git branch [分支名] // 在git 工作路径下执行即可
切换分支
git checkout [分支名]
通过查看分支情况
git log --decorate --oneline,观察head指针
–graph 选项表示让git绘制分支图
git log --oneline --decorate --graph --all
合并分支
git merge [分支名] //将[分支名]分支合并到HEAD所在的分支(一般为master)上
git merge feature
删除分支
git branch -d [分支名]
将当前分支推送到远程端
git push origin/gitee //origin 是一般是第一个添加的远程仓库的默认名称,gitee是第二个添加的远程仓库名称,这个根据自己定义的来
git有两种合并方式: Fast-forward 和Three-way merge
- Fast-forward
所谓的 Fast-forward 就是当待合并的分支位于目标分支的直接上游时,Git 只需把目标分支的指针直接移动即可实现合并
- Three-way merge
如果待合并的两个分支不在同一条线上,那么进行合并就需要解决一个根本的问题 —— 冲突!
对于冲突的处理,Git 相对来说是比较机智的。
举个例子:
合并 C3 和 C4 得到 C5,但 C5 应该如何处理“冲突”呢?
SVN 会把问题抛给用户,让用户自行解决;Git 则显得更为高明,它会找到第三个快照,然后综合三者特点自动解决冲突。
那第三个快照应该如何决定呢?
没错,应该找两者的共同“祖先”作为参照物,一比较就知道两个分支都干了些什么。
图片中 C3 和 C4 的共同祖先是 C1,可以看到 C3 和 C4 分别增加了 test2.py 和 test1.py 两个文件。因为对比之后发现三者并没有冲突,所以 C5 应该是三者的合体,即同时拥有 common.py、test1.py 和 test2.py 三个文件(有兴趣的鱼油不妨测试一下)。
另外,值得一提的是,Git 这种合并方式也适用于同名文件的不同更改。
举个例子:
这里 C3 和 C4 都只有一个文件(test.txt),但是内容却不一样。如果这样合并,你猜 Git 会不会报“冲突”?
答案是不会的!
因为 Git 找到它们的共同祖先 C1,可以看到 C3 和 C4 都是在 C1 的基础上进行添加(C4 在第 2 行添加了“I”,C3 在第 4 行增加了“FishC”,C1 第 3 行的“love”是它们共同拥有的),同时在每一行并没有产生冲突的地方,所以自动合并后的 C5 是这样的:
# test.txt
I
love
FishC
这里贴上小甲鱼的讲解链接,有图有真相,灰常建议学习:
- 容易混淆的指令: checkout 和 reset
checkout 可以用来切换分支 ,切换分支的同时,工作区的文件也就变了,事实上和回滚类似,都是改变工作区文件内容
git checkout [分支名]
checkout 也可以用来恢复文件
git checkout --[文件名]
文件名前带-- 是为了预防你恰好有一个分支叫做 README.md,那么它就搞不懂你要恢复文件还是切换分支了,所以约定两个横杆(–)后边跟的是文件名
恢复文件会同时覆盖暂存区域和工作目录
reset 可以用来回滚快照
git reset [快照版本号or head^or head~]
reset回滚快照可以使用–hard --soft选项
reset 也可以用来恢复文件,此时不能使用–hard --soft选项
git reset [文件名] //文件名前面是否可以加–,用来区分快照还是文件?类似checkout用法只将制定文件恢复到暂存区域
reset --hard 和checkout的区别
第一个区别是,对于 reset --hard 命令来说,checkout 命令更安全。因为 checkout 命令在切换分支前会先检查一下当前的工作状态,如果不是“clean”的话,Git 不会允许你这样做;而 reset --hard 命令则是直接覆盖所有数据。
另一个区别是如何更新 HEAD 指向,reset 命令会移动 HEAD 所在分支的指向,而 checkout 命令只会移动 HEAD 自身来指向另一个分支
如果使用 git reset --hard [分支名] 是比较危险的操作,
举个例子:
git reset --hard feature
如果master和分支feature有不同的文件,这个操作会加个HEAD->所在的分支(master)指向feature分支,那么master分支原有的不同文件就会丢失,因此不安全
不过这可以处理你pull错误的情况,你本地是util分支,你想切换分支,结果pull 成了 sh分支;带来了很多sh分支和util分支不同的改变,这时候暂存区的文件都不是你想要的,这时候git reflog找到util最后一个提交版本的版本号lastversion,然后git reset --hard laseversion ;即可清理暂存区的文件,回退到上一个版本
- 尽量使用 三方合并Three-way merge 而不是Fast-forward
Fast-forward 合并版本后,使用git log --decorate --oneline --graph查看分支情况,根本看不到原来分支版本存在过
如果我们确实希望保留分支版本信息,可以使用 --no-ff选项进行合并,这时候git会使用Three-way merge进行合并
git merge --no-ff feature
10 和 11 的细致区别 建议点击进行学习:
Git实用教程11:匿名分支和checkout命令(有彩蛋)
二.工作区 暂存区 git仓库的区别
工作区域(Working Directory)就是你平时存放项目代码的地方。
暂存区域(Stage)用于临时存放你的改动,事实上它只是一个文件,保存即将提交的文件列表信息。
Git 仓库(Repository)就是安全存放数据的位置,这里边有你提交的所有版本的数据。其中,HEAD 指向最新放入仓库的版本(这第三棵树,确切的说,应该是 Git 仓库中 HEAD 指向的版本)。
OK,Git 的工作流程一般是酱紫:
-
在工作目录中添加、修改文件;
-
将需要进行版本管理的文件放入暂存区域;
-
将暂存区域的文件提交到 Git 仓库。
三. 工作流程
常设分支
一般为主分支(master)和开发分支(devlop)两个即可
另外的功能分支(feature),预发布分支(release)和维护分支(hotfix)属于临时分支,用完之后应该及时删除。

四. 本地git和远程github关联与取消
创建SSH key
ssh-keygen -t rsa -C “youremai@example.com”
本地git执行
git remote add origin [github仓库链接]
git remote add origin https://github.com/kevin-mei/study_git
考虑到国内访问github比较慢,可能会同时加两个远程仓库目录,gitee下的;
git remote add gitee [your gitee url]
后面提交的时候,git push gitee [gitee上的分支名] // 这时候就不能用origin了
origin 默认是github的远程仓库名
将本地master 推向远程仓库
//加上-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令
git push -u origin master
下一次推送,就不用加-u参数了
git push origin master
本地已经关联了github ,从远程出获取更新
git pull origin master
取消本地目录下关联的远程库
git remote remove origin
从远程仓库克隆
git clone https://github.com/kevin-mei/study_git
五. Git更新远程仓库代码到本地 git fetch
查看远程分支:
git remote -v
从远程获取最新版本到本地, 建议在本地新建 一个temp分支,将远程origin仓库的master分支代码下载到temp分支上
git fetch origin mast:temp
比较本地仓库和下载的temp分支
git diff temp
合并temp分支到本地的master分支
git merge temp
删除temp分支
git branch -d temp
六. 删除暂存区文件
git add * 添加了无用的文件到暂存区,可以使用下面命令进行删除
git rm [文件名] --cached
git rm -f [文件夹名] --cached
七. 清理编译的中间文件:
# 删除 untracked files
git clean -f
# 连 untracked 的目录也一起删掉
git clean -fd
# 连 gitignore 的untrack 文件/目录也一起删掉 (慎用,一般这个是用来删掉编译出来的 .o之类的文件用的)
git clean -xfd
# 在用上述 git clean 前,墙裂建议加上 -n 参数来先看看会删掉哪些文件,防止重要文件被误删
git clean -nxfd
git clean -nf
git clean -nfd
参考文献: