git

Git 学习笔记

GIT 是一款免费的、开源的、分布式的版本控制系统。每一个 GIT 克隆都是一个完整的文件库,含有全部历史记录和修订追踪能力。其最大特色就是“分支”及“合并”操作快速、简便。支持离线工作,GIT 是整个项目范围的原子提交,而且 GIT 中的每个工作树都包含一个具有完整项目历史的仓库。

Git 安装

https://git-scm.com/download/
如果你不想安装,可以访问 http://www.hubwiz.com/course/55d301543ad79a1b05dcc4e2/ 这个链接直接练习。

查看 Git 版本

git --version

创建一个新的 Git 仓库

创建新文件夹,打开,然后执行 git init 命令用来创建一个新的 git 仓库,git 大部分命令都是在 git 仓库下运行

1
2
3
4
git init # 将当前目录转换为 git 仓库
git init <directory> # 将特定目录转换为 git 仓库
git init --bare <directory> # 指定目录创建一个空的(裸的)git 仓库,它不包含工作目录,并且不能提交编辑和提交修改,该仓库主要用于远端服务器管理代码,保存 git 历史提交的版本信息,防止冲突。
git clone [url] # 复制一个存在的 git 仓库到本地

git init 和 git init –bare 的区别?

Git 的目录结构

git-init

1
2
3
4
5
6
7
8
HEAD # 指向 Git 项目当前分支的头指针
config # Git 项目配置信息
hooks # 默认的 'hooks' 脚本,被特定事件发生前后触发。
objects # Git 的数据对象,包括:commits, trees, blobs, tags。
branches # Git 项目分支信息,新版 Git 已经不再使用该目录
description # Git 项目描述信息
info # 里面含一个 exclude 文件,指 Git 项目要忽略的文件。
refs # 指向所有 Git 项目分支的指针

所有的分支指针保存在 .git/refs/heads 目录下,HEAD 在 .git/HEAD 目录下,标签在 .git/refs/tags 目录下。

忽略不必要的文件/敏感信息

在 Git 工作区的根目录下创建一个特殊的 .gitignore 文件,然后把要忽略的文件名填进去,Git 就会自动忽略这些文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 配置语法
# 以斜杠“/”开头表示目录;
# 以星号“*”通配多个字符;
# 以问号“?”通配单个字符
# 以方括号“[]”包含单个字符的匹配列表;
# 以叹号“!”表示不忽略(跟踪)匹配到的文件或目录;
# {!ab}:必须不是此类型
# {ab,bb,cx}:代表ab,bb,cx中任一类型即可
# [abc]:代表a,b,c中任一字符即可
# [ ^abc]:代表必须不是a,b,c中任一字符

# 此为注释 – 将被 Git 忽略
*.a # 忽略所有 .a 结尾的文件
!test.json # 但 test.json 除外
/TODO # 仅仅忽略项目根目录下的 TODO 文件
build/ # 忽略目录下的所有文件
doc/*.txt # 会忽略 doc/ 文件夹下的所有以 .txt 结尾的
.DS_Store
.idea

Git 工作流

你的本地仓库由 git 维护的三棵“树”组成。第一个是你的工作目录,它持有实际文件;第二个是暂存区(Index),它像个缓存区域,临时保存你的改动;最后是 HEAD,它指向你最后一次提交的结果。
trees

Git 配置

git config 命令用来配置本地安装的 git
Git的设置文件为 .gitconfig 它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cat ~/.gitconfig # 查看当前本地配置
git config --list # 显示当前的 Git 配置
git config -e [--global] # 编辑 Git 配置文件

git config [--global] user.name "[name]" # 配置当前仓库修改提交作者名
git config [--global] user.email "[email address]" # 配置本地所有仓库提交 email 地址
git config [--global] color.ui true # 打开所有的默认终端着色
git config [--global] core.editor vim # 设置默认编辑器
git config [--global] alias.co checkout # 设置别名,使用如下 git co
git config [--global] alias.ci commit #命令用来将本地跟踪的修改添加到本地仓库历史
git config [--global] alias.st status # 命令用于查看当前工作区和暂存区的状态信息
git config [--global] alias.br branch # 命令用于查看当前分支

git config [--global] --unset alias.br # 删除别名

更多自定义 Git - 配置 Git

添加和提交

git add 你可以提出更改(把它们添加到暂存区)
git commit 命令用来将本地修改添加到本地仓库历史,你的改动已经提交到了 HEAD,但是还没到你的远端仓库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
git add [file1] [file2] # 添加指定文件到暂存区
git add [dir] # 添加指定目录到暂存区,包括子目录
git add . # 添加当前目录的所有文件到暂存区
git add prefix_* # 匹配以 prefix 开头的所有文件
git add *.js # 匹配以 js 结尾的所有文件
git add -p # 添加每个变化前,都会要求确认
git add -u # 只加修改过的档案, 新增的档案不加入

git commit -m [message] # 提交暂存区到仓库区
git commit [file1] [file2] ... -m [message] # 提交暂存区的指定文件到仓库区
git commit -a # 提交工作区自上次 commit 之后的变化,直接到仓库区
git commit -a -m 'commit -message' # 将所有修改过得档案都 commit, 不需要执行 git-add 命令 .-a 参数就是已经自动执行 git-add 命令
git commit -a -v # -v 可以看到档案哪些内容有被更改, -a 把所有修改的档案都 commit
git commit -v # 提交时显示所有 diff 信息
git commit --amend -m [message] # 使用一次新的commit,替代上一次提交,如果代码没有任何新变化,则用来改写上一次commit的提交信息
git commit --amend [file1] [file2] ... # 重做上一次commit,并包括指定文件的新变化
git commit --amend --no-edit # 加入 --no-edit 标记会修复提交但不修改提交信息

删除文件/改名文件

1
2
3
4
git rm [file1] [file2] ... # 删除工作区文件,并且将这次删除放入暂存区
git rm [r] --cached [file] # 停止追踪指定文件,但该文件会保留在工作区

git mv [file-original] [file-renamed] # 改名文件,并且将这个改名放入暂存区

清除没有在 Git 库中的文件

1
2
git clean -nd # 查看当前多的文件和目录或将要被删除的文件和目录
git clean -fd # 将多的文件和目录从 git 目录里删除

查看信息

git log 查看历史记录
gitlog
git 一直停留在 log 模式,这时只需要按 q 键即可退出。如果不退出,在按完 q 键后回车即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
git status # 显示有变更的文件

git log # 显示当前分支的版本历史
git log --stat # 会显示在每个提交 (commit) 中哪些文件被修改了, 这些文件分别添加或删除了多少行内容
git log -2 # 查看最近2次的提交日志
git log -p # 除了 git log 信息之外,包含哪些文件被更改了,以及每个文件相对的增删行数。
git log --oneline # 查看历史提交日志,单行显示
git log --pretty=oneline # 查看版本号,同上(版本号更详细)
git log --graph --pretty=oneline --abbrev-commit # 可以看到分支的合并情况(简化版)
git log --graph # 分支合并图(详细图) 同 git log
git log -S [keyword] # 搜索提交历史,根据关键词
git log [tag] HEAD --pretty=format:%s # 显示某个 commit 之后的所有变动,每个 commit 占据一行
git log [tag] HEAD --grep feature # 显示某个 commit 之后的所有变动,其"提交说明"必须符合搜索条件
git log --follow [file] # 显示某个文件的版本历史,包括文件改名
git log --since="2 weeks ago" # 最后这2周的log
# 自定义的 git log 配置
git log --graph --abbrev-commit --decorate --all --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(dim white) - %an%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n %C(white)%s%C(reset)'


git shortlog -sn # 显示所有提交过的用户,按提交次数排序
git blame [file] # 关于此档案的所有 commit 纪录,显示指定文件是什么人在什么时间修改过(通常找出来谁改动了某个文件里的某行代码会很有用)
git blame -C [file] # 显示内容来自哪个文件

git diff # 显示暂存区和工作区的差异
git diff --cached # 看看哪些文件将被提交(commit)
git diff HEAD # 显示工作区与当前分支最新 commit 之间的差异
git diff [first-branch]...[second-branch] # 显示两次提交之间的差异
git diff --shortstat "@{0 day ago}" # 显示今天你写了多少行代码

git show [commit] # 显示某次提交的元数据和内容变化
git show --name-only [commit] # 显示某次提交发生变化的文件
git show [commit]:[filename] # 显示某次提交时,某个文件的内容
git show HEAD # 此版本修改的资料
git show HEAD^ # 前一版修改的资料
git show HEAD~4 # 前前前前一版修改的资料
git reflog # 显示当前分支的最近几次提交,记录每一次命令

修正错误的 commit

git reset 命令用来撤销历史中的某次提交,也会撤销其后面的提交历史

1
2
3
4
5
6
7
8
9
10
11
12
13
14
git reset [file] # 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变
git reset --hard # 重置暂存区与工作区,与上一次commit保持一致
git reset [commit] # 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变
git reset --hard HEAD^ # 回到上一个版本
git reset --hard HEAD~2 # 命令将当前分支向前倒退两个提交
git reset --keep [commit] # 重置当前HEAD为指定commit,但保持暂存区和工作区不变
git reset --soft * # --soft 参数告诉 Git 重置 HEAD 到另外一个 commit,但也到此为止

git revert [commit] # 新建一个commit,用来撤销指定 commit, 后者的所有变化都将被前者抵消,并且应用到当前分支

git checkout [file] # 恢复暂存区的指定文件到工作区
git checkout [commit] [file] # 恢复某个commit的指定文件到暂存区和工作区
git checkout . # 恢复暂存区的所有文件到工作区
git checkout -- file # 我 git add 增加到暂存区后,接着添加内容,我想通过撤销命令让其回到暂存区后的状态(删除了也可以恢复)

Git 分支理解与应用

分支是用来将特性开发绝缘开来的。在你创建仓库的时候,master 是“默认的”分支。在其他分支上进行开发,完成后再将它们合并到主分支上。
branches

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
git checkout -b dev(分支名) # 创建分支并切换过去,-b 参数表示创建并切换,相当于 git branch dev , git checkout dev
git branch # 查看当前所有本地分支
git branch -r # 列出所有远程分支
git branch -a # 列出所有本地分支和远程分支
git branch [branch-name] # 新建一个分支,但依然停留在当前分支
git branch -m [branch-name] [new-branch-name] # 重命名本地分支
git branch --track [branch] [remote-branch] # 新建一个分支,与指定的远程分支建立追踪关系
git branch --set-upstream [branch] [remote-branch] # 建立追踪关系,在现有分支与指定的远程分支之间

git branch -d [branch-name] # 删除分支
git branch -D [branch-name] # 强制删除分支

git push origin --delete [branch-name] # 删除远程分支
git branch -dr [remote/branch] # 删除远程分支

git checkout [branch-name] # 切换到指定分支,并更新工作区
git checkout - # 切换到上一个分支
git checkout master # 切换回主分支

git merge [branch] # 合并指定分支到当前分支
git cherry-pick [commit] # 选择一个commit,合并进当前分支
git merge --no-ff -m '' [branch] # 合并并删除分支,被删除的分支信息还在

处理合并冲突 Git merge conflict

mergerdev
git diff [fileName] 查看区别
编辑查看文件,git 已为我们做好标记区别, 删除你不要的部分并保存,git add [fileName]

代码合并:Merge、Rebase 的选择

git rebase 和 git merge 做的事其实是一样的。它们都被设计来将一个分支的更改并入另一个分支,只不过方式有些不同。
查看详细

Git 基础 - 打标签

标签可以针对某一时间点的版本做标记,常用于版本发布。
https://git-scm.com/book/zh/v1/Git-%E5%9F%BA%E7%A1%80-%E6%89%93%E6%A0%87%E7%AD%BE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
git tag # 列显已有的标签
git tag <name> # 新建一个标签,默认为 HEAD,也可以指定一个 commit id
git tag -a v0.1.2 -m “0.1.2版本” # 创建附注标签
git tag -s <tagname> -m "blablabla..." # 可以用PGP签名标签
git checkout [tagname] # 切换到标签
git show v0.1.2 # 查看标签的版本信息
git tag -d v0.1.2 # 删除标签
git tag -a v0.1.1 9fbc3d0 # 补打标签
git tag -v [tag-name] # (译注:取 verify 的首字母)的方式验证已经签署的标签。此命令会调用 GPG 来验证签名,所以你需要有签署者的公钥,存放在 keyring 中,才能验证
git checkout -b [branch] [tag] # 新建一个分支,指向某个tag

git push origin v0.1.2 # 将 v0.1.2 标签提交到 git 服务器
git push origin --tags # 将本地所有标签一次性提交到 git 服务器
git push origin :refs/tags/[tagName] # 从远程删除

git fetch origin tag V1.2 # 精准拉取指定的某一个远程版本

Git stash 改善工作流

备份当前的工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时,将当前的工作区内容保存到 Git 栈中。
查看廖雪峰 git 教程详情

1
2
3
4
5
6
7
8
git stash save "message..." # 这条命令实际上是 git stash 命令的完整版。git 会基于当前的提交信息自动创建评论。如果你更希望有自定义信息的话(因为它可能和前一个提交没有任何联系)
git stash list # 显示进度列表
git stash apply # 取出来
git stash apply stash@{num}
git stash drop # 从堆栈上移除
git stash pop stash@{num} # 取出然后从记录就删除

git stash clear # 删除所有存储的进度

Git 远程同步

1
2
3
4
5
6
7
8
9
10
git fetch [remote] # 下载远程仓库的所有变动
git remote # 查看远程仓库信息
git remote -v # 显示当前所有远程库的详细信息,显示格式为 远程库名字 url 连接(类型)
git remote show [remote] # 显示某个远程仓库的信息
git remote add [shortname] [url] # 增加一个新的远程仓库,并命名
git pull [remote] [branch] # 取回远程仓库的变化,并与本地分支合并

git push [remote] [branch] # 上传本地指定分支到远程仓库
git push [remote] --force # 强行推送当前分支到远程仓库,即使有冲突
git push [remote] --all # 推送所有分支到远程仓库

假设现在想增加 3 个远程库地址

1
2
3
https://git.oschina.net/****/*.git 
https://coding.net/****/*.git
https://github.com/****/*.git

首先,先增加第一个地址 git remote add origin <url1>
然后增加第二个地址 git remote set-url --add origin <url2>
增加第三个地址 git remote set-url --add origin <url3>
⋯ 依次类推

这样就完成了添加多个地址到 origin 库中了,
以后只要使用 git push origin master 就可以一次性 push 到 3 个库里面了(使用 git push 也可)

生成一个可供发布的压缩包

git archive

Github 贡献代码工作流

学习参考

  1. Fork 到自己的项目保持同步
  2. Clone 到本地,如果项目有依赖包,还要安装依赖包
  3. 进入本地项目目录,upstream 是你取的别名 git remote add upstream [原作者项目url]
  4. 保持同步fetch(‘拿来、取来’) git fetch upstreamgit checkout mastergit merge upstream/mastergit push origin master;或者 git pull upstream master
  5. 创建分支 git checkout -b [dev-rebase]
  6. 修改添加代码
  7. git statusgit add.git commit -m '...'
  8. 写了 3 天多后考虑到那边可能更新了代码,执行 git checkout master
  9. 同步 git pull upstream master
  10. git checkout [dev-rebase]
  11. git rebase master
  12. 推送 git push origin [dev-rebase]

Github 实用小技巧

  1. 查看每日最新资讯 https://github.com/trending/php
  2. github 根据你 following 定期给你发一封邮件 https://github.com/explore/subscribe
  3. 进入到别人的项目中按快捷键 t 进行模糊搜索
  4. s 定位到搜索框
  5. gi => issues
  6. gp => pulls

学习参考

https://kingofamani.gitbooks.io/git-teach/content/chapter_2/git_q_and_a.html
http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
http://rogerdudler.github.io/git-guide/index.zh.html
https://www.atlassian.com/git/tutorials/setting-up-a-repository/&prev=search
http://backlogtool.com/git-guide/cn/intro/intro1_1.html
https://github.com/geeeeeeeeek/git-recipes/blob/master/wiki/catagory.md

如果对您有用,请博主喝杯咖啡!

热评文章