目录
安装 git
已有?请跳过
初始化
基本配置
配置帐号信息
1 2 3 4
| $ git config [--local | --global | --system] user.name 'Your name'
$ git config [--local | --global | --system] user.email 'Your email'
|
当然你也可以通过修改 .git 文件目录下面的 config 文件进行修改
配置别名
1 2 3 4 5
| $ git config --global alias.st status $ git config --global alias.co checkout $ git config --global alias.br branch $ git config --global alias.ci commit
|
查看配置
1 2 3 4
| git config --list [--local | --global | --system]
git cat-flie [-p / -t]
|
参数说明
- local:区域为本仓库
- global: 当前用户的所有仓库
- system: 本系统的所有用户
缺省等同于 local
优先级:local > global > system
生成 shh 密钥
如果你想通过 https 的方式 每次提交输入密码,当然可以跳过此节
1 2 3 4 5 6
| $ ssh-keygen -t rsa
$ ssh-keygen -t rsa -C "youremail"
|
生成的 id_rsa 是私钥 生成的 id_rsa.pub 是公钥
在对应服务器增加密钥。【github -> setting -> SSH and GPG keys】
如果公司是自己搭建的 git 服务(未使用 gitlab),则交给管理员添加。如果使用 gitlab 在设置增加密钥
获取 Git 仓库
在现有目录中初始化仓库
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ git init ['your_project'/缺省]
$ git status
$ git add [file1] [file2] ...
$ git commit -m "提交message"
$ git remote add origin [远程地址]
$ git push -u origin master
|
克隆现有的仓库
1 2 3 4
| $ git clone [url] <fileName/缺省>
$ git clone --bare [ 连接地址 ] < file bf名称 >
|
从裸仓库 clone 下来的本地仓库可以进行正常的 push 操作, 但是从一般仓库 clone 下来的本地仓库却不行。 这也正是裸仓库存在的意义。 裸仓库一般情况下是作为远端的中心仓库而存在的。
本地已有构建的项目
1 2 3 4 5 6 7 8
| $ git remote -v $ git remote add github <url> $ git fetch github $ git merge -h $ git merge --allow-unrelated-histories github/master
$ git push github
|
不进行版本控制
添加不进行版本控制的文件目录
项目目录下 新建 .gitignore 文件 ,写入不需要进行版本控制的文件名或文件夹
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| node_modules
doc *doc
doc/ *doc/
*.md // 对 .md结尾的文件 不进行版本控制
doc !doc/*
|
提交 commit 后,想再忽略一些已经提交的文件
- 把忽略的文件添加到 .gitignore;
- 通过
git rm --cached < file >
的方式删除掉 git 仓库里面无需跟踪的文件。
你需要确认 的 云端源 也要删除
git commit -m 'delete git remote somefile'
git push
常见操作
查看信息
查看帮助 git help
1 2 3 4 5 6 7 8
| $ git help [--all/-a]
$ git help [--guide/-g]
$ git help git
|
查看状态 git status
git status 命令用于显示工作目录和暂存区的状态。git status 不显示已经 commit 到项目历史中去的信息。看项目历史的信息要使用 git log
常用于 git commit 之前, 这样能防止你不小心提交了您不想提交的东西。
1 2 3 4 5 6 7
| $ git status
$ git status -uno
$ git status -s
|
查看变化 git diff
对比 修改之后还没有暂存起来的内容变化
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 diff
$ git diff <file>
$ git diff <id1><id1><id2>
$ git diff <branch1> <branch2> $ git diff --staged
$ git diff --cached
$ git diff --stat
$ git diff HEAD
$ git diff test
$ git diff HEAD -- readme.md
$ git diff -- readme.md
$ git diff --cached -- readme.md
$ gti diff [分支名称/commit-id] [分支名称/commit-id] --< file >
$ git diff [commit号] [commit号]
$ git diff HEAD HEAD^[同 HEAD~1]
$ git diff HEAD HEAD^^[同HEAD~2]
|
补充说明:
- 一个节点,可以包含多个子节点(checkout 出多个分支)
- 一个节点可以有多个父节点(多个分支合并)
- 是~都是父节点,区别是跟随数字时候,2 是第二个父节点,而~2 是父节点的父节点
- ^和~可以组合使用,例如 HEAD~2^2
查看日志 git log
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| $ git log --all
$ git log --all --graph
$ git log --oneline
$ git log --oneline -n4
$ git log --oneline --all -n4 --graph
$ git help --web log
$ git log -1 // 最近一次提交信息
|
查看某个文件的版本历史 git show
1 2 3 4
| // 先查看文件提交历史 git log --pretty=oneline [文件名或文件路径] // 例如src/AfterView/common/commonStream.vue
git show [版本号] // 显示具体的某次的改动的修改
|
图形化查看提交内容 gitk
定制化图形界面 : view --> new view [勾选 all refs] # 显示全部分支
更新
1 2 3 4
| $ git pull
$ git pull origin master
|
1 2 3 4 5 6 7 8
| $ git fetch orgin master
$ git log -p master ..origin/master
$ git merge origin/master
|
文件重命名
1 2 3 4 5 6
| $ mv [文件名1] [文件名2] $ git add ['文件名'] $ git rm ['文件名']
|
1 2 3
| $ git mv ['旧文件名'] ['新文件名']
|
1 2 3 4 5
| $ git reset --hard [提交版本号|缺省]
$ git reflog
|
文件删除
1 2 3 4
| $ rm <file> $ git add ['文件名']
|
如果删除出错 借助 git reset --hard 进行撤销
提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| $ git add ['文件名' | '.'代表全部]
$ git commit -m'这里填写提交日志'
$ git pull
$ git push
|
撤销&回滚
简单总结
- 修改了工作区,恢复:git checkout
- add 后,想撤销: git reset HEAD
- commit 后,想撤销: git reset --hard [需要回退的 commit id]
撤销
修改文件 尚未提交
1 2 3
| $ git checkout <fileName> $ git checkout .
|
- 文件执行了 git add 操作,恢复 文件(index 内回滚)
1 2 3 4 5 6 7 8 9
| $ git reset HEAD fileName
$ git checkout < fileName >
$ git checkout [commitid] -- <file>
|
- 同时对多个文件执行了 git add 操作,本次只想提交其中一部分文件
1 2 3 4
| $ git add * $ git status
$ git reset HEAD <filename>
|
修改文件 已经提交(git commit)到 本地仓库
- 修改 git commit 不再产生新的 Commit[ 只能修改最近一次 ]
1 2 3 4
| $ git add sample.txt
$ git commit --amend -m"说明"
|
- 多次 git commit 撤销到其中某次 Commit
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| $ git reset --[soft/hard/mixed] [commit|HEAD]
$ git reset [file]
$ git reset --hard
$ git reset [commit]
$ git reset --hard [commit]
|
回滚
已进行 git push,即已推送到“远程仓库”中。我们将已被提交到“远程仓库”的代码还原操作叫做“回滚”!
注意:对远程仓库做回滚操作是有风险的,需提前做好备份和通知其他团队成员!
还原 远端服务器 提交的代码
1 2 3 4 5
| $ git checkout <tag>
$ git checkout <commitID> <filename>
|
删除最后一次远程提交
1 2 3
| $ git revert HEAD $ git push origin master
|
1 2 3
| $ git reset --hard HEAD^ $ git push origin master -f
|
二者区别:
revert 是放弃指定提交的修改,但是会生成一次新的提交,需要填写提交注释,以前的历史记录都在;
reset 是指将 HEAD 指针指到指定提交,历史记录中不会出现放弃的提交记录。
回滚某次提交
1 2 3 4
| $ git log
$ git revert commitID
|
删除某次提交
1 2 3 4 5 6 7 8 9 10 11
| $ git log --oneline -n5
$ git rebase -i "commit id"^
$ git rebase -i [父级commit id ]
$ git rebase -i [开始commit 的父级id] [结束commit id]
|
如果没有指定 结束 commit,那么结束 commit 默认为当前分支最新的 commit,那么 rebase 结束后会自动更新当前分支指向的 commit,
如果指定了结束 commit,而且结束 commit 不是当前分支最新的 commit,那么 rebase 后会有生成一个 游离的 head,,而且当前分支指向的 commit 不会更新
具体还可参考:
Deleting a Git commit
在 Git 中,如何『删除』commit?
操作标签
标签操作允许为存储库中的特定版本提供有意义的名称。
创建标签
1 2 3 4 5 6 7 8 9 10
| $ git tag -a 'tag1' -m 'tag1的说明' [HEAD / commit id / 缺省]
$ git push origin <tagname>
$ git push origin --tags
|
查看标签
1 2 3 4 5 6
| $ git tag
$ git tag -l
$ git show tagName
|
删除标签
1 2 3 4 5 6 7 8 9 10 11
| $ git tag -l
$ git tag -d <tagName>
$ git push origin --delete tag <tagname>
$ git push origin :refs/tags/标签名
|
操作分支
查看分支
1 2 3 4
| git branch -v
$ git branch -av
|
新建分支
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| $ git branch dev2
$ git checkout -b <branchname>
$ git checkout -b <branchname> [commit号/分支名称]
$ git checkout -b <branchname> [commit版本号]
$ git checkout -b <本地分支名x> <origin/远程分支名x>
/* 相当于分别执行了下面两条命令 */
|
提交到远程分支
1 2 3 4 5 6 7 8 9 10
| $ git push [origin] <分支名称>:<分支名称>
$ git pull [origin] <分支名称> 更新远程分支到本地
$ git branch --set-upstream-to=[origin]/<分支名称>
$ git branch -vv
|
[origin] 代指 添加远程裸仓库地址时候,创建的名称
删除分支
1 2 3 4 5 6 7 8 9
| $ git branch [-D/-d] <branchname>
$ git branch -d -r <branchname> $ git push origin :<branchname>
$ git branch $ git push origin --delete <branchname>
|
合并分支
fast-forward
- fast-forward 方式 合并
这种方法相当于直接把 master 分支移动到 test 分支所在的地方,并移动 HEAD 指针
1 2 3 4
| $ git checkout master
$ git merge dev
|
- no-fast-forward 方式 合并
这种合并方法会在 master 分支上新建一个提交节点,从而完成合并
1 2 3 4
| $ git checkout master
$ git merge –no-ff dev
|
- squash 方式 合并
squash 和 no-ff 非常类似,区别只有一点不会保留对合入分支的引用
1 2
| $ git checkout master $ git merge –squash dev
|
- rebase 方式 合并
rebase 与 merge 不同,rebase 会将合入分支上超前的节点在待合入分支上重新提交一遍,变成线性历史
1 2 3 4
| $ git checkout master
$ git rebase dev
|
- cherry-pick 挑拣 合并
对已经存在的 commit 进行 再次提交 [选择某些节点进行合并]
1 2
| $ git cherry-pick <commit id>
|
当执行完 cherry-pick 以后,将会 生成一个新的提交;这个新的提交的哈希值和原来的不同,但标识名 一样;
图解 4 种 git 合并分支方法 > git cherry-pick 的使用
暂存
当收到紧急任务,手里又存在未完成的模块可以先放到暂存区
1 2 3 4 5 6 7 8
| git stash
git stash list
git stash apply [序号/缺省为stash@{0}]
git stash pop [序号/缺省为stash@{0}]
|
分离头【detached HEAD】
执行 git checkout [commit 版本号] ,git 会提示显示处于分离头(无分支状态),在此状态下,进行的提交操作不挂到在分支下,直接切换分支,会导致分离头的提交丢失。
错误示范:
1 2 3 4 5 6 7 8 9
| git checkout 15a6686b624
git commit -am"错误示例" git branch -av
git checkout marst
git branch [分支名称] [commit版本号]
|
正常使用
1 2 3 4
| git checkout -b [分支名称] [commit版本号] // 创建并切换分支
git checkout -b 本地分支名x origin/远程分支名x // 基于 远端分支 建立 本地分支(远程分支名x) 采用此种方法建立的本地分支会和远程分支建立映射关系
|
操作子仓库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| $ git submodule add <仓库地址> <本地路径>
$ git submodule init
$ git submodule update
$ git submodule update --init --recursive
$ git rm -r --cached <本地路径>
|
git submodule 使用小结
常用命令详解
git pull 详解
git pull 相当于从远程获取最新版本并 merge 到本地
1 2 3 4
| $ git pull
$ git pull origin master
|
git pull 详解
1 2 3 4 5
| $ git pull [<options/缺省>] [<远端仓库名称> [<分支名称>…]]
|
git fetch 详解
git fetch 相当于是从远程获取最新到本地,不会自动 merge
在实际使用中,git fetch 更安全一些
使用 git fetch 进行更新
1 2 3 4 5 6 7 8
| $ git fetch orgin master
$ git log -p master ..origin/master
$ git merge origin/master
|
OR
1 2 3 4 5 6
| $ git fetch origin master:tmp
$ git diff tmp
$ git merge tmp
|
git pull = git fetch + git merge
git add 详解
将修改添加到暂存区
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| $ git add .
$ git add *
$ git add -u
$ git add -A
$ git add *Controller
$ git add Hello*
$ git add Hello?
|
git commit 详解
用于将更改记录(提交)到存储库
1 2 3 4 5 6 7 8 9 10 11
| $ git commit -m "the commit message"
$ git commit -a $ git commit -a -m "the commit message"
$ git commit --amend
|
git remote 详解
git remote 命令管理一组跟踪的存储库
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
|
$ git remote
$ git remote [-v | --verbose]
$ git remote add [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=<fetch|push>] <name> <url>
$ git remote rename <old> <new>
$ git remote remove <name>
$ git remote set-head <name> (-a | --auto | -d | --delete | <branch>) $ git remote set-branches [--add] <name> <branch>…
$ git remote get-url [--push] [--all] <name>
$ git remote set-url [--push] <name> <newurl> [<oldurl>]
$ git remote set-url --add [--push] <name> <newurl> $ git remote set-url --delete [--push] <name> <url> $ git remote [-v | --verbose] show [-n] <name>… $ git remote prune [-n | --dry-run] <name>… $ git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)…]
|
git push 详解
将修改添加到暂存区
语法
1 2
| $ git push <远程主机名/缺省> <本地分支名/缺省>:<远程分支名/缺省>
|
示例
origin 可通过 .git config 查看地址
完整示例
1 2
| $ git push origin master
|
本地分支名 缺省
表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。
1 2 3 4
| $ git push origin :master
$ git push origin --delete master
|
本地分支、远程分支都 缺省
表示推送特定主机的对应分支简写方式:如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。
远程主机名、本地分支、远程分支都 缺省
表示推送origin 主机的对应分支简写方式:如果当前分支只有一个追踪分支,那么主机名都可以省略。
当前分支与多个主机存在追踪关系,则可以使用-u 选项指定一个默认主机,这样后面就可以不加任何参数使用 git push
1 2
| $ git push -u origin master
|
simple 方式 和 matching 方式
不带任何参数的 git push,默认只推送当前分支,这叫做 simple 方式
matching 方式,会推送所有有对应的远程分支的本地分支
Git 2.0 版本之前,默认采用 matching 方法,现在改为默认采用 simple 方式
如果要修改这个设置,可以采用 git config 命令
1 2 3
| $ git config --global push.default matching
$ git config --global push.default simple
|
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
|
$ git push --all origin
$ git push --force origin
$ git push origin --tags
$ git push origin tag_name
$ git push origin :tag_name
$ git push origin HEAD
$ git push origin HEAD:master
$ git push -f origin dev:refs/dev_op
$ git push origin :refs/dev //删除远程的dev分支 $ git push origin dev:refs/dev_op
|
git branch 详解
用于列出,创建或删除分支
语法
1 2 3 4 5 6 7 8 9 10 11 12
|
$ git branch [-r | -a]
$ git branch [-f] <branchname>
$ git branch (-m | -M) <oldbranch> <newbranch>
$ git branch (-d | -D) <branchname>
|
使用-d 在删除前 Git 会判断在该分支上开发的功能是否被 merge 的其它分支。如果没有,不能删除。如果 merge 到其它分支,但之后又在其上做了开发,使用-d 还是不能删除。-D 会强制删除
示例
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
| $ git branch
$ git branch -r
$ git branch -a
$ git branch -vv
$ git branch dev2
$ git branch -m dev2
$ git branch -d <branchname>
$ git branch -d -r <branchname> $ git push origin :<branchname>
$ git branch $ git push origin --delete dev2
|
git checkout 详解
用于切换分支或恢复工作树文件。这条命令会重写工作区
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 checkout <branch>
$ git checkout <branch> <fileName>
$ git checkout <fileName>
$ git checkout -b <branch> $ git checkout -b|-B <new_branch> [<start point>]
$ git checkout -b newBranch origin/newBranch
$ git checkout -- <fileName>
$ git checkout -- <fileName>
$ git checkout [-q] [<commit id>] [--] <paths>
$ git checkout [-q] [--] <paths>
$ git checkout --orphan <new_branch>
$ git checkout --merge <branch> $ git checkout -m <branch>
|
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| $ git checkout master
$ git checkout tag_name
$ git checkout master file_name
$ git checkout commit_id file_name
$ git checkout -b dev/1.5.4 origin/dev/1.5.4
$ git checkout -- hello.rb
$ git checkout -- '*.c'
$ git checkout .
|
git reset 详解
1 2 3 4 5 6 7 8 9
| $ git reset [ –-soft | -–mixed | -–hard] <commit>
$ git reset HEAD --< files >
|
git cherry-pick 详解
语法
1 2 3 4 5 6 7 8 9
| $ git cherry-pick [<options>] <commit-ish>...
|
git submodule 详解
命令用于初始化,更新或检查子模块
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ git submodule status [--cached] [--recursive] [--] [<path>…]
$ git submodule add <url> [<path>]
$ git submodule init [--] [<path>…]
$ git submodule update
$ git submodule update --init --recursive
|
git 原理
git 工作解析图
下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:
git 文件目录
- COMMIT_EDITMSG
- config 当前 git 的配置文件
- description (仓库的描述信息文件)
- HEAD (指向当前所在的分支),例如当前在 develop 分支,实际指向地址是 refs/heads/develop
- hooks [文件夹]
- index
- info [文件夹]
- logs [文件夹]
- objects [文件夹] (存放所有的 git 对象,对象哈希值前 2 位作为文件夹名称,后 38 位作为对象文件名, 可通过 git cat-file -p 命令,拼接文件夹名称+文件名查看)
- ORIG_HEAD
- refs [文件夹]
• heads (存放当前项目的所有分支)
• tags (存放的当前项目的所有标签,又叫做里程碑)
commit 与 tree 和 blob 的关系
1 2 3 4 5
| commit 对应一个tree
tree 包含文件[blob],如果下级还是文件夹,则又是一个tree
blob 是tree下面具体文件 【与文件名无关具体到文件内容】
|
git 注意事项
- checkout reset 慎用
- 禁止向集成分支[多人使用分支] 执行 push -f [强制更新到远端 可能会导致远端所在分支回退很多版本]
如果单人自行分支,确认是要返回某个节点, 使用 push -f
公共分支修改 commit : git reflog 命令查找历史,然后利用 git reset --hard [提交版本号|缺省] 的方式恢复
- 公共分支 禁止进行 rebase 变基操作
对于自己在本地的多次 commit,我想把他合并成一次 commit,还没有 push 的情况下,使用 rebase
常见缩写
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| -d --delete:删除
-D --delete --force的快捷键
-f --force:强制
-m --move:移动或重命名
-M --move --force的快捷键
-r --remote:远程
-a --all:所有
|