目录
17、stash 储藏
17.2 描述
17.3 基本用法
18、tag 标签
18.1 描述
18.2 基本用法
19、fetch 获取
19.1 描述
19.2 基本用法
20、pull 整合
20.1 描述
20.2 基本用法
20.3 pull 与 fetch 的区别
21、push 更新推送
21.1 描述
21.2 基本用法
22、remote 管理
22.1 基本用法
23、submodule 管理子模块
23.1 使用场景
23.2 描述
23.3 基本用法
24、show 显示
24.1 描述
24.2 基本用法
25、shortlog 汇总
25.1 基本用法
26、describe 显示最近标签
26.1 描述
26.2 基本用法
27、rebase 合并修改
27.1 示例
用于将更改储藏在脏工作目录中。
git stash list []
git stash show []
git stash drop [-q|--quiet] []
git stash ( pop | apply ) [--index] [-q|--quiet] []
git stash branch []
git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
[-u|--include-untracked] [-a|--all] []
git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
[-u|--include-untracked] [-a|--all] [-m|--message ]]
[--] […]]
git stash clear
git stash create []
git stash store [-m|--message ] [-q|--quiet]
当要记录工作目录和索引的当前状态,但想要返回干净的工作目录时,使用 git stash
保存本地修改,并恢复工作目录以匹配 HEAD
提交;
list
列出所储藏的修改,show
进行检查,apply
恢复,默认情况下,储藏列表”分支名称上的 WIP “,但可以在创建一个消息时在命令行上给出具体描述性的消息;
创建的最新储藏存储在 refs/stash
中,这个引用中的反垃圾中会发现较旧的垃圾邮件,并且可以使用通常的 reflog 语法命名(stash@{0}
是最近创建的垃圾邮件),也可以通过指定存储空间索引来引用锁存。
当发现本地的更改与上游的更改冲突时,git pull
拒绝覆盖您的更改,此时可以隐藏更改,执行 git pull
,再解压缩:
git pull
...
file foobar not up to date, cannot merge.
$ git stash
$ git pull
$ git stash pop
当要处理紧急的事务从而不得不中断自己的工作流程时,应该提交临时分支来存储更改并返回原始分支进行紧急修复:
$ git checkout -b my_wip // 临时分支
$ git commit -a -m "WIP" // 临时提交
$ git checkout master // 返回主分支
$ edit emergency fix # 编辑内容 // 紧急修复
$ git commit -a -m "Fix in a hurry" // 提交修复
$ git checkout my_wip // 返回临时分支
$ git reset --soft HEAD^ // 移位值最新的提交的头位置
可使用 git stash
来简化:
$ git stash // 临时储藏
$ edit // 处理
$ git commit -a -m 'fix' // 紧急处理
$ git stash pop // 获取最近一次储藏的内容,之后删除栈中对应的 stash
当修改文件后,想要切换分支但不想提交当前进行的工作,此时可以往栈中推送新的储藏:
$ git stash
Saved working directory and index state \
"WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")
# 查看现有的储藏
$ git stash list
若想应用之前的变更,可以通过 apply
进行指定应用,不指定将会使用最近的存储:
$ git stash apply
# On branch master
# Changes not staged for commit:
# (use "git add ..." to update what will be committed)
#
# modified: index.html
# modified: lib/simplegit.rb
--重新暂存被暂存的文件
$ git stash apply --index
--移除储藏的文件
$ git stash drop stash@{0}
通过取消该储藏的补丁使得取消之前所储藏的修改:
$ git stash show -p stash@{0} | git apply -R
# 不指定储藏的索引将会选择最近的储藏
-- 设置别名
$ git config --global alias.stash-unapply '!git stash show -p | git apply -R'
$ git stash apply
$ #... work work work
$ git stash-unapply
当储藏了一些工作之后继续工作,重新储藏将会归并冲突,若想重新检验储藏变更,创建新分支,成功将会丢弃储藏:
$ git stash branch testchanges
git tag [-a | -s | -u ] [-f] [-m | -F ]
[ |
创建标签可以:用于在开发阶段,某个阶段的完成,创建一个版本,在开发中都会使用到,指向软件开发中的一个关键时期;
不能创建已经存在的标签,除非指定 -f
;
创建标签对象以及一个标签消息:-a
、-s
或 -u
,使用 -m
或 -F
,否则将启动编辑器自主输入标签消息;
标签类型:
轻量级标签,像不会变化的分支,实际上就是个指向特定提交对象的引用;
含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来签署或验证。
$ git tag
$ git tag -l 'v1.4.2.*'
$ git tag -a v1.4 -m 'my version 1.4'
# 轻量级标签
$ git tag v1.4-lw
# git show 查看响应标签的版本信息,包括标签对象
--$ git show v1.4
tag v1.4
Tagger: Scott Chacon <[email protected]>
Date: Mon Feb 9 14:45:11 2009 -0800
my version 1.4
commit 15027951111...3b3ff6
Merge: 4a41117... a611117...
Author: n <[email protected]>
Date: Sun Feb 18 10:10:10 2009 -0800
如果有自己的私钥,还可用 GPG 来签署标签:
$ git tag -s v1.5 -m 'my signed 1.5 tag'
$ git tag -d v1.0
$ git tag -v v1.4
object 883653babd11111116a5c392bb739348b1eb61
type commit
tag v1.4
tagger 1C 1<[email protected]> 111111111-0700
GIT 1.4
$ git tag -a v1.2 9fceb11
默认情况下不会把标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库。运行 git push origin [tagname]
:
$ git push origin --tags
Counting objects: 50, done.
Compressing objects: 100% (38/38), done.
Writing objects: 100% (44/44), 4.56 KiB, done.
Total 44 (delta 18), reused 8 (delta 1)
To [email protected]/1.git
* [new tag] v0.1 -> v0.1
* [new tag] v1.2 -> v1.2
* [new tag] v1.4 -> v1.4
* [new tag] v1.4-lw -> v1.4-lw
用于从另一个存储库中下载对象和引用。
git fetch [] [ […]]
git fetch []
git fetch --multiple [] [( | )…]
git fetch --all []
从一个或多个其他存储库中获取分支或标签(引用)以及完成其历史所必需的对象**;
远程跟踪以更新,需要将这些更新获取回本地;
默认情况下还会获取正在获取的历史记录的任何标签;
可以从单个命名的存储库或 URL 中,也可以从多个存储库中获取;
获取的参考名称以及它们所指向的对象名称被写入到 .git/FETCH_HEAD
中。
# 从远程 refs/heads/ 命名空间复制所有分支,并存储到本地 refs/remotes/origin/ 中
$ git fetch origin
# 从远程分支 pu 和 maint 提取到本地 pu 和 tmp
$ git fetch origin +pu:pu maint:tmp
$ git fetch git://git.1.org/1/git.git maint
# 使用FETCH_HEAD来检查具有git-log的分支
$ git log FETCH_HEAD
$ git fetch <远程主机名>
# 更新所有分支
$ git fetch
# 指定远程主机的指定分支
$ git fetch <远程主机名> <分支名>
# 查看远程分支
$ git branch -a
* master # 本地的当前分支
remotes/origin/master # 远程分支
用于从另一个存储库或本地分支获取并集成(整合)到本地分支。
git pull [options] [ […]]
默认模式下,git pull
是 git fetch
后跟 git merge FETCH_HEAD
的缩写;
git pull
使用给定的参数运行git fetch
,并调用git merge
将检索到的分支头合并到当前分支中。
$ git pull origin next:master
# 合并当前分支则省略 : 冒号
# 手动建立追踪关系
$ git branch --set-upstream master origin/next
# 合并
$ git pull origin
# 若当前分支只有一个跟踪分支,则可以省略远程主机名
$ git pull
# 采用 rebase 模式
$ git pull --rebase <远程主机名> <远程分支名>:<本地分支名>
$ git fetch origin master # 下载最新版本都本地
$ git log -p master..origin/master # 比较分支差别
$ git merge origin/master # 合并
git pull origin master
用于将本地分支的更新,推送到远程主机。格式与 pull 相似。
$ git push <远程主机名> <本地分支名>:<远程分支名>
git push [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=]
[--repo=] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
[-u | --set-upstream] [--push-option=]
[--[no-]signed|--sign=(true|false|if-asked)]
[--force-with-lease[=[:]]]
[--no-verify] [ […]]
使用本地引用更新远程引用,同时发送完成给定引用所需的对象;
可以在每次推入存储库时,通过在那里设置挂钩触发一些事件;
当不指定使用
参数时,将查询当前分支的 branch.*.remote
以此确定位置。
# 推送本地空的分支
$ git push origin :master
# 等同于
$ git push origin --delete master
-u
指定默认主机:$ git push -u origin master # 后面可直接使用 git push
simple
方法( V2.0 之前默认 matching ):$ git config --global push.default matching
# 或者
$ git config --global push.default simple
# 推送所有远程主机
$ git push --all origin
# 强制推送,产生一个 非直进式 合并
$ git push --force origin
# 推送标签,默认不推送
$ git push origin --tags
# 将远程分支推送到远程同名下
$ git push origin HEAD
# 将当前分支推送到源存储库中的远程引用匹配主机
$ git push origin HEAD:master
# 推送新分支
$ git push origin lbranch-1:refs/rbranch-1
# 补充原有分支
$ git rebase rbranch-1
$ git push origin lbranch-2:refs/rbranch-1
# 覆盖远程分支
$ git push -f origin lbranch-2:refs/rbranch-1
--或者
$ git push origin :refs/rbranch-1 //删除远程的rbranch-1分支
$ git push origin lbranch-1:refs/rbranch-1
$ gitk rbranch-1
$ git push origin tag_name
# 删除远程标签
$ git push origin :tag_name
git remote [-v | --verbose]
git remote add [-t ] [-m ] [-f] [--[no-]tags] [--mirror=]
git remote rename
git remote remove
git remote set-head (-a | --auto | -d | --delete | )
git remote set-branches [--add] …
git remote get-url [--push] [--all]
git remote set-url [--push] []
git remote set-url --add [--push]
git remote set-url --delete [--push]
git remote [-v | --verbose] show [-n] …
git remote prune [-n | --dry-run] …
git remote [-v | --verbose] update [-p | --prune] [( | )…]
git remote
# --verbose 显示对应的克隆地址
$ git remote -v
# taging 指代对应的仓库
$ git remote add staging git://git.kernel.org/.../gregkh/staging.git
# 列出分支
$ git remote
# 更新远程分支
$ git fetch staging
# 查看分支关系
$ git branch -r
# 切换到远程分支
$ git checkout -b github/master
$ git remote add -f -t master -m master origin git://example.com/git.git
$ git merge origin
git submodule [--quiet] add [] [--] []
git submodule [--quiet] status [--cached] [--recursive] [--] […]
git submodule [--quiet] init [--] […]
git submodule [--quiet] deinit [-f|--force] (--all|[--] …)
git submodule [--quiet] update [] [--] […]
git submodule [--quiet] summary [] [--] […]
git submodule [--quiet] foreach [--recursive]
git submodule [--quiet] sync [--recursive] [--] […]
git submodule [--quiet] absorbgitdirs [--] […]
当项目越来越多的时候,常常会需要提取一个公共的库给多个项目使用,此时会有:
如何在 git 项目中导入库?
库在其他项目中被修改了可以更新到远程代码库?
其他库如何获取库的最新的提交?
如何在 clone 的时候自动导入库?
submodule 是一个很好的多项目使用共同类库的工具。
允许类库项目为 repository,子项目为一个单独的 git 项目存在父项目中,子项目可以有自己的独立的commit
,push
,pull
;
父项目以 Submodule 的形式包含子项目,父项目可以指定子项目 header;
父项目中的提交信息包含 Submodule 的信息,clone 父项目时可以把 Submodule 初始化。
添加子模块:
$ git submodule add http://github.com/chaconinc/DbConnector
.gitmodules
文件,该配置文件保存了 URL 与已经拉取的本地目录之间的映射:$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: .gitmodules
new file: DbConnector
$ cat .gitmodules
[submodule "DbConnector"]
path = DbConnector
url = http://github.com/chaconinc/DbConnector
如果有多个子模块,该文件就会有多条记录;
如果
.gitignore
文件一样受到版本控制;
克隆含有子模块的项目:
$ ls -la
drwxr-xr-x 13 schacon staff 442 Sep 17 15:21 .git
-rw-r--r-- 1 schacon staff 92 Sep 17 15:21 .gitmodules
drwxr-xr-x 2 schacon staff 68 Sep 17 15:21 DbConnector
...
git submodule init
用来初始化本地配置文件,而 git submodule update
则从该项目中抓取所有数据并检出父项目中列出的合适的提交:$ git submodule init
Submodule 'DbConnector' (http://github.com/chaconinc/DbConnector) registered for path 'DbConnector'
$ git submodule update
Cloning into 'DbConnector'...
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 11 (delta 0), reused 11 (delta 0)
Unpacking objects: 100% (11/11), done.
Checking connectivity... done.
Submodule path 'DbConnector': checked out 'c3f01dc8862123d317dd46284b05b6892c7b29bc'
--recursive
进行自动初始化并更新仓库中的每一个子模块:$ git clone --recursive http://github.com/chaconinc/MainProject
# 不支持直接删除,需手动删除:
git rm --cached pod-library
rm -rf pod-library
rm .gitmodules
更改git的配置文件config:
vim .git/config
# 删除后进行提交远程服务器
git commit -a -m 'remove pod-library submodule'
git show [options] …
显示一个或多个对象(blobs
,树,标签和提交);
显示日志消息和文本差异,还以 git diff-tree --cc
生成的特殊格式呈现合并提交;
显示标签消息和引用对象;
显示树的名称(相当于 git ls-tree
和 --name-only
);
显示 blobs 的普通的内容;
通常用来显示提交引入的更改。
$ git show v1.0.0
$ git show v1.0.0^{tree}
$ git show -s --format=%s v1.0.0^{commit}
$ git show next~10:README
$ git show master:Makefile master:t/Makefile
git log --pretty=short | git shortlog []
git shortlog [] [] [[\--] …]
如果在命令行上没有传递修订版本,并且标准输入不是终端或没有当前的分支,则 git shortlog
将输出从标准输入读取的日志的摘要,而不引用当前存储库。
$ git shortlog -s -n
135 Tom Preston-Werner
15 Jack Danger Canty
-s
省略每次 commit 注释仅仅返回一个简单统计;
-n
按照 commit 数量从多到少进行排序。
显示离当前提交最近的标签。
简介:
git describe [--all] [--tags] [--contains] [--abbrev=] […]
git describe [--all] [--tags] [--contains] [--abbrev=] --dirty[=]
查找从提交可访问的最新标记;
如果标签指向提交,则只显示标签。 否则,它将标记名称与标记对象之上的其他提交数量以及最近提交的缩写对象名称后缀;
默认情况下(不包括--all
或--tags
) git 描述只显示注释标签。
$ git describe --tags
tag1-2-g026498b
2
:表示自打tagtag1
以来有2
次提交(commit);
g026498b
:g 为git的缩写,在多种管理工具并存的环境中很有用处;
git rebase [-i | --interactive] [options] [--exec ] [--onto ]
[ []]
git rebase [-i | --interactive] [options] [--exec ] [--onto ]
--root []
git rebase --continue | --skip | --abort | --quit | --edit-todo
merge 合并:
# 1.
$ git checkout -b mywork origin
# 2.
$ vi file.txt
$ git commit
# 3.
$ git pull ...
rebase 合并:
$ git checkout mywork
$ git rebase origin
该命令会把”mywork
“分支里的每个 commit 取消掉,并临时保存为补丁(patch 在”.git/rebase
“),然后把”mywork
“ 更新 ”origin
“ ,最后把补丁应用到”mywork
“上。
更新 mywork 之后,会指向新的提交,丢弃旧的提交。
运行垃圾收集命令(pruning garbage collection), 删除被丢弃的提交。
rebase 过程中也会出现冲突,git 会停止 rebase,解决完冲突后,add 更新内容的索引,无需 commit ,只需要:
$ git rebase --continue
此时 git 会 apply 余下的 补丁。
--abort
来终止 rebase 操作。并且 mywork 会回到 rebase 开始前的状态:$ git rebase --abort