2019独角兽企业重金招聘Python工程师标准>>>
本文使用命令和命令的基本含义作为标题,旨在快速查找常用命令。
环境配置
git config(配置文件设置)
Git 自带一个 git config
的工具来帮助设置配置文件。
这些变量存储在三个不同的位置:
|
|
当前使用仓库的 Git 目录中的 |
我们也可以不加参数代表从所有配置文件读写文件。 |
每一个级别覆盖上一级别的配置,覆盖关系为local > global > system.
下面举个例子:
-- 查看系统配置文件
$ git config --system --list-- 查看用户配置文件
$ git config --global --list-- 查看项目配置文件
$ git config --local --list-- 查看所有配置文件
$ git config --list
git config --list(查看配置文件)
此命令可以配合配置文件标识查看不同级别配置文件内容
-- 查看系统配置文件
$ git config --system --list-- 查看用户配置文件
$ git config --global --list-- 查看项目配置文件
$ git config --local --list-- 查看所有配置文件
$ git config --list
git config <key> <value>(修改配置文件)
此命令用于修改配置文件内容。
可以使用配置文件标识修改指定配置文件内容。
$ git config --global user.name "lic"
.gitignore文件(忽略提交)
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为.gitignore
的文件,列出要忽略的文件模式。
例子忽略了IDEA、maven、日志和svn生成的文件。
# --> IDEA
.idea/
*.iml# --> maven
target/# --> log
logs/# --> svn
.svn/
基本操作
git help <verb>(获取帮助)
使用此命令可以获取到git关于此命令的帮助手册
$ git help config
git init (初始化仓库)
如果你打算使用 Git 来对现有的项目进行管理,你只需要进入该项目目录并输入
$ git init
该命令将创建一个名为 .git
的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。
“.git”目录中的文件结构如下
$ ls
config description HEAD hooks/ info/ objects/ refs/
config | git配置文件 |
description | 仓库的描述信息,主要给gitweb等git托管系统使用 |
HEAD | 这个文件包含了一个档期分支(branch)的引用 |
hooks/ | 这个目录存放一些shell脚本,可以设置特定的git命令后触发相应的脚本;在搭建gitweb系统或其他git托管系统会经常用到hook script |
info/ | 包含仓库的一些信息 |
objects/ | 所有的Git对象都会存放在这个目录中,对象的SHA1哈希值的前两位是文件夹名称,后38位作为对象文件名 |
refs/ | 这个目录一般包括三个子文件夹,heads、remotes和tags,heads中的文件标识了项目中的各个分支指向的当前commit |
git add<file name>(跟踪文件、存入暂存区、标记已解决)
这是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。 将这个命令理解为“添加内容到下一次提交中”而不是“将一个文件添加到项目中”要更加合适。
放在项目目录下的文件默认情况下是不受Git管理的,你可通过 git add
命令来实现对指定文件的跟踪。
-- 添加某个文件
$ git add README.md-- 添加全部文件(.为通配符)
$ git add .
git clone <url>(克隆仓库)
如果你想获得一份已经存在了的 Git 仓库的拷贝,这是就要使用此命令。
这是 Git 区别于其它版本控制系统的一个重要特性,Git 克隆的是该 Git 仓库服务器上的几乎所有数据,而不是仅仅复制完成你的工作所需要文件。 当你执行 git clone
命令的时候,默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。 事实上,如果你的服务器的磁盘坏掉了,你通常可以使用任何一个克隆下来的用户端来重建服务器上的仓库
Git 支持多种数据传输协议。 https://
协议、 git://
协议以及SSH协议。使用SSH协议时需要在远程仓库配置本机公钥才能生效。
-- https协议
git clone https://git.oschina.net/imlichao/git-example.git-- SSH协议
git clone git@git.oschina.net:imlichao/git-example.git
git status(查看文件状态)
要查看哪些文件处于什么状态,可以用此命令。
$ git status
提示主要有一下几部分内容:
-- 所在分支和跟踪分支
On branch dev_5.2
Your branch is up-to-date with 'origin/dev_5.2'.-- 没有文件变更
nothing to commit, working tree clean-- 未被Git管理文件(可以git add添加跟踪)
Untracked files:(use "git add <file>..." to include in what will be committed)documents/new_filenothing added to commit but untracked files present (use "git add" to track)-- 没有提保存暂存区的文件(可以git add保存到暂存区、git checkout放弃修改、git commit -a直接提交)
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git checkout -- <file>..." to discard changes in working directory)modified: README.mdno changes added to commit (use "git add" and/or "git commit -a")-- 暂存区未提交的文件(可以git reset HEAD返回工作区)
Changes to be committed:(use "git reset HEAD <file>..." to unstage)modified: README.md-- 未推送到远程分支的提交数量(可以git push推送到远程分支)
On branch dev_5.2
Your branch is ahead of 'origin/dev_5.2' by 1 commit.(use "git push" to publish your local commits)
nothing to commit, working tree clean
git status --short(状态简览)
git status
命令的输出十分详细,但其用语有些繁琐。 如果你使用 git status -s
命令或 git status --short
命令,你将得到一种更为紧凑的格式输出。 运行 git status -s
,状态报告输出如下:
$ git status -sM README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt
新添加的未跟踪文件前面有 ??
标记,新添加到暂存区中的文件前面有 A
标记,修改过的文件前面有 M
标记。 你可能注意到了 M
有两个可以出现的位置,出现在右边的 M
表示该文件被修改了但是还没放入暂存区,出现在靠左边的 M
表示该文件被修改了并放入了暂存区。 例如,上面的状态报告显示: README
文件在工作区被修改了但是还没有将修改后的文件放入暂存区,lib/simplegit.rb
文件被修改了并将修改后的文件放入了暂存区。 而 Rakefile
在工作区被修改并提交到暂存区后又在工作区中被修改了,所以在暂存区和工作区都有该文件被修改了的记录。
git diff(差异比较)
我们要比较工作区、暂存区以及仓库分支中文件的差异时可以使用此命令。
下面的命令如果不加<file name>表示比较所有文件差异
git diff <file name>(工作区与暂存区比较)
$ git diff README.md
git diff <branch name> <file name>(工作区与分支比较)
$ git diff dev_5.2 README.md
git diff --cached <file name>(暂存区与当前分支比较)
$ git diff --cached README.md
git diff --staged <file name>(暂存区与当前分支比较)
和--cached一样两种方式一种效果
$ git diff --staged README.md
git diff --cached <branch name><file name>(暂存区与其他分支比较)
$ git diff --cached master README.md
git diff <branch name> <branch name><file name>(分支与分支比较)
$ git diff dev_5.2 master README.md
git commit(提交文件)
现在的暂存区域已经准备妥当可以提交了。 在此之前,请一定要确认还有什么修改过的或新建的文件还没有git add
过,否则提交的时候不会记录这些还没暂存起来的变化。 这些修改过的文件只保留在本地磁盘。 所以,每次准备提交前,先用 git status
看下,是不是都已暂存起来了, 然后再运行提交命令 git commit
git commit
这种方式会启动文本编辑器以便输入本次提交的说明。(提交说明必须要填)
git commit -m <commit message>(直接添加提交说明)
我们也可以直接使用 -m 参数直接填写说明
git commit -m "commit explain"
git commit -a(跳过暂存区直接提交)
尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁琐。 Git 提供了一个跳过使用暂存区域的方式, 只要在提交的时候,给 git commit
加上 -a
选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add
步骤:
$ git commit -a
git rm (删除文件)
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用 git rm
命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
$ git rm documents/test
由于git rm是从暂存区域移除,回退操作要使用git reset HEAD从暂存区撤销,再用git checkout -- 恢复工作区文件。如果已经提交可以使用git reset进行回退。
-- 已删除文件恢复到工作区
$ git reset HEAD documents/test
Unstaged changes after reset:
D documents/test
-- 已删除文件恢复到暂存区
$ git checkout -- documents/test
git mv <file path> <path>(移动文件)
文件file path移动到path目录。
$ git mv documents/new ./
git mv <file name> <new name>(文件重命名)
文件名从file name更改为new name
$ git mv new new1
实际上相当于执行了以下操作
$ mv README.md README
$ git rm README.md
$ git add README
git log(查看提交历史)
默认不用任何参数的话,git log
会按提交时间列出所有的更新,最近的更新排在最上面。 正如你所看到的,这个命令会列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明。
git log -p(附带内容差异)
此命令展示提交历史时附带内容差异
$ git log -p
git log --stat(附带提交统计)
展示提交历史时附带统计信息。如那个文件变化几行,增加内容还是减少内容等信息。
git log --stat
git log --pretty=(指定显示样式)
这个选项可以指定使用不同于默认格式的方式展示提交历史。 这个选项有一些内建的子选项供你使用。 比如用 oneline
将每个提交放在一行显示,查看的提交数很大时非常有用。 另外还有 short
,full
和 fuller
可以用,展示的信息或多或少有些不同,请自己动手实践一下看看效果如何。
$ git log --pretty=oneline
git log --graph(分支合并线图)
当 oneline 或 format 与另一个 log
选项 --graph
结合使用时尤其有用。 这个选项添加了一些ASCII字符串来形象地展示你的分支、合并历史:
$ git log --graph
git log -- <file path>(某个文件的提交)
$ git log -- documents/test
git log -S <string>(变更了某些字符串的提交)
$ git log -S "git"
git cherry-pick <commit id>(选择应用提交)
cherry-pick允许我们提取一个或多个现有的提交,并使用这些提交的快照来创建新的提交。这个功能在处理生产bug时将会非常有用。
$ git cherry-pick 3016bb0b1a3deede145d5f93773ffc7928f22e73
[master 4aff2cc] experimentDate: Mon Apr 16 10:48:55 2018 +08002 files changed, 3 insertions(+), 1 deletion(-)
由于使用cherry-pick创建的提交标识名都是一致的,所以两个应用了同一提交的分支在合并时并不会产生冲突,git会完美的将他处理成一次提交。
git reset HEAD^(版本回退)
将HEAD指针和当前分支指针回退一个提交版本。
一个“^”符号代表回退一个版本,三个就回退三个版本。
$ git reset HEAD^
git reset <commit id>(指定提交版本回退)
我们可以制定回退到某一次提交
$ git reset 3016bb0
git reflog(操作日志)
此命令用于查看操作日志。git所有的操作在这里都能找到。
$ git reflog
3016bb0 (HEAD -> bug) HEAD@{0}: reset: moving to 3016bb0
5e96789 HEAD@{1}: reset: moving to HEAD^
3016bb0 (HEAD -> bug) HEAD@{2}: reset: moving to 3016bb0
3016bb0 (HEAD -> bug) HEAD@{3}: reset: moving to HEAD^
b5b1cff HEAD@{4}: checkout: moving from master to bug
6bef1e9 (master) HEAD@{5}: commit: experiment
如果我们将已提交代码进行了回退但是,发现回退错了。这时候在 git log中是无法找到记录的。这是我们就可以使用reflog命令查找到那次提交记录,然后用reset命令指定到回退前的提交编号。 如下图: |
撤销操作
git checkout -- <file>...(撤销工作区修改)
此命令使用了checkout其实真正的含义是,从上次提交的文件重新检出。你需要知道 git checkout -- [file]
是一个危险的命令,这很重要。 你对那个文件做的任何修改都会消失 - 你只是拷贝了另一个文件来覆盖它。 除非你确实清楚不想要那个文件了,否则不要使用这个命令。
$ git checkout -- README.md
撤销所有工作区修改
$ git checkout -- .
git reset HEAD <file>...(撤销暂存文件)
文件从暂存区撤销到工作区
$ git reset HEAD README.md
Unstaged changes after reset:
M README.md
撤销所有暂存区修改
$ git reset HEAD .
git commit --amend(重新提交)
有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend
选项的提交命令尝试重新提交
$ git commit --amend
这个命令会将暂存区中的文件提交。 如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令),那么快照会保持不变,而你所修改的只是提交信息。
储藏场景
git stash(储藏场景)
有时,当你在项目的一部分上已经工作一段时间后,所有东西都进入了混乱的状态,而这时你想要切换到另一个分支做一点别的事情。 问题是,你不想仅仅因为过会儿回到这一点而为做了一半的工作创建一次提交。 针对这个问题的答案是 git stash
命令。
储藏会处理工作目录的脏的状态 - 即,修改的跟踪文件与暂存改动 - 然后将未完成的修改保存到一个栈上,而你可以在任何时候重新应用这些改动。
需要注意的是工作区和暂存区的代码会全部被贮藏。
git stash
git stash save <message>(储藏并添加注释)
git stash save "stash注释"
git stash list(查看储藏列表)
$ git stash list
stash@{0}: WIP on master: 5e96789 experiment
stash@{1}: WIP on master: 5e96789 experiment
stash@{2}: On bug: Uncommitted changes before rebase
git stash apply <stash id>(恢复储藏并保留)
如果想要应用其中一个更旧的储藏,可以通过名字指定它,像这样:git stash apply stash@{2}
。 如果不指定一个储藏,Git 认为指定的是最近的储藏
恢复的时候如果不加参数将会将储藏得所有内容恢复到工作区,如果增加了--index参数则会分别恢复到红作区和暂存区。
$ git stash apply stash@{2}
git stash pop <stash id>(恢复储藏并删除)
就像apply一样将内容恢复,但是回复后的内容将从储藏区删除。
$ git stash pop stash@{2}
git stash clear(清空整个储藏区)
将储藏区所有内容全部清空,一旦清空这些代码将永久丢失。所以要小心。
$ git stash clear
git stash drop <stash id> (删除单个储藏)
$ git stash drop <stash@{id}>
远程仓库
git remote(查看远程仓库)
如果想查看你已经配置的远程仓库服务器,可以运行 git remote
命令。 它会列出你指定的每一个远程服务器的简写。 如果你已经克隆了自己的仓库,那么至少应该能看到 origin - 这是 Git 给你克隆的仓库服务器的默认名字
$ git remote
origin
你也可以指定选项 -v
,会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL。
$ git remote -v
origin ssh://git@192.168.17.247:10022/PL_service_department/pmall.git (fetch)
origin ssh://git@192.168.17.247:10022/PL_service_department/pmall.git (push)
git remote add <shortname> <url>(添加远程仓库)
创建一个新的远程仓库
$ git remote add pb https://github.com/paulboone/ticgit
git remote rename <remote-name><new remote-name>(远程仓库重命名)
$ git remote rename origin origin1
git remote rm <remote-name>(删除远程仓库)
git remote rm origin1
git fetch(从远程仓库拉取)
这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。
必须注意 git fetch
命令会将数据拉取到你的本地仓库 - 它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。
$ git fetch
此命令是仓库级别的,fatch会将所有分支的变更都拉下来。
git fetch <remote-name>(指定远程仓库拉取)
指定拉取代码的仓库名称
$ git fetch origin
git pull(拉取远程仓库&合并远程分支)
从远程仓库拉取变更并自动合并当前分支。pull命令会先执行fetch命令将远程仓库的变更拉取到本地,然后尝试将当前分支与对应的跟踪分支进行merge合并。
$ git pull
这里注意fatch是仓库级别的而pull是分支级别的。
git pull --rebase(拉取远程仓库&变基远程分支)
当我们希望拉取分支后执行的不是merge而是rebase时我们可以使用此命令
git pull --rebase
我们也可以修改配置文件让pull默认执行rebase
git config --global pull.rebase true
git pull <remote-name> <branch-name>(指定拉取合并远程分支)
拉取后与指定分支进行合并
$ git pull origin dev_5.3
git push(推送到远程分支)
当你想分享你的项目时,必须将其推送到远程分支。此命令将当前分支推送至跟踪的远程分支。
git push
这里注意fatch是仓库级别的而push是分支级别的。
git push <remote-name> <branch-name>(指定远程分支推送)
当前分支推送到指定的分支
git push origin master
git push <remote-name> <branch-name>:<origin branch-name>(指定远程分支推送)
当本地分支与远程分支不同名时使用此命令
git push origin mymaster:master
git push -u <remote-name><branch name>(创建远程分支)
将本地创建的分支推送到远程仓库
git push -u origin <branch name>
-u 表示添加本地分支与远程分支的跟踪分支。
git push -u <remote-name><branch name>:<origin branch name>(创建远程分支)
我们也可以创建与本地分支不同名的远程分支
git push -u origin mymaster:master
git push <remote-name>--delete <branch-name>(删除远程分支)
git push origin --delete serverfix
git push <remote-name> :<origin branch name>(删除远程分支)
将一个空分支推送给远程分支实现删除操作。
git push origin :master
标签管理
git tag(查看标签)
这个命令以字母顺序列出标签;但是它们出现的顺序并不重要。
$ git tag
git tag -n(查看标签带注释)
$ git tag -n
git tag -l(筛选标签)
你也可以使用特定的模式查找标签。 例如,Git 自身的源代码仓库包含标签的数量超过 500 个。 如果只对 1.8.5 系列感兴趣,可以运行:
$ git tag -l 'v1.8.5*'
git tag <tag name>(创建轻量标签)
一个轻量标签很像一个不会改变的分支 - 它只是一个特定提交的引用。与svn不同git的标签是不可以移动的。
$ git tag v6.0
git tag -a <tag name> -m <message>(创建附注标签)
附注标签是存储在 Git 数据库中的一个完整对象。 它们是可以被校验的;其中包含打标签者的名字、电子邮件地址、日期时间;还有一个标签信息;并且可以使用 GNU Privacy Guard (GPG)签名与验证。
$ git tag -a v1.4 -m 'my version 1.4'
git tag -a <tag name> <commit id>(历史提交上打标签)
你也可以对过去的提交打标签。
$ git tag -a v1.2 9fceb02
git tag -d <tag name>(删除标签)
$ git tag -d v6.0
Deleted tag 'v6.0' (was e26bdca)
git push origin <tag_name>(标签推送到远程仓库)
$ git push origin v5.5
git push origin --tags(所有标签推送到远程仓库)
$ git push origin --tags
git push <remote-name> :<origin tag name>(删除远程标签)
将一个空标签推送给远程分支实现删除操作。
git push origin :v1.0.0
git checkout -b <branch_name> <tag_name>(从标签检出分支)
git checkout -b master v6.0
分支管理
git branch(查看分支)
$ git branchdev_5.2
* master
git branch <branch name>(创建分支)
创建分支时会在当前所在的提交对象上创建一个指针。
创建分支时很容易被理解成从当前分支创建一个分支,其实git并没有考虑分支之间的关系。只不过当前分支也凑巧指向了当前所在的提交,所以只是创建了指向当前提交的指针与其它分支无关。
git branch -d <branch name>(删除分支)
git branch -d hotfix
git branch -v (查看分支附带最后一次提交)
$ git branch -v
* bug1 fe13e9b 生产环境修改一个bugdev_5.2 fe13e9b [ahead 5] 生产环境修改一个bugmaster fe13e9b [ahead 5] 生产环境修改一个bug
git branch -vv (查看分支附带跟踪分支)
从远程分支创建的本地分支,都会自动创建一个跟踪分支来维护本地分支与远程分支的对应关系。
我们在pull或push代码时就会与对应的远程分支进行交互。
$ git branch -vv
* bug1 fe13e9b 生产环境修改一个bugdev_5.2 fe13e9b [origin/dev_5.2: ahead 5] 生产环境修改一个bugmaster fe13e9b [origin/master: ahead 5] 生产环境修改一个bug
这会将所有的本地分支列出来并且包含更多的信息,如每一个分支正在跟踪哪个远程分支与本地分支是否是领先、落后或是都有。
git branch --set-upstream-to=<remote branch>(指定跟踪分支)
我们想自己指定本地分支的远程跟踪分支时使用此命令
$ git branch --set-upstream-to=origin/dev_5.2
Branch bug1 set up to track remote branch dev_5.2 from origin.
git branch -a (查看全部分支包括远程分支)
$ git branch -a
* bug1dev_5.2masterremotes/origin/HEAD -> origin/masterremotes/origin/dev_5.2remotes/origin/master
git branch --merged(已合并到当前分支的分支)
$ git branch --merged
git branch --no-merged(未合并到当前分支的分支)
$ git branch --no-merged
git checkout <branch name>(分支切换)
Git有一个名为HEAD的特殊指针,指向当前所在的本地分支(译注:将 HEAD
想象为当前分支的别名)。
切换分支就是将HEAD指针指向目标分支而已。
git checkout testing
分支切换会改变你工作目录中的文件 在切换分支时,一定要注意你工作目录里的文件会被改变。 如果是切换到一个较旧的分支,你的工作目录会恢复到该分支最后一次提交时的样子。 如果 Git 不能干净利落地完成这个任务,它将禁止切换分支。 |
git checkout -b <branch name>(创建并切换分支)
想要新建一个分支并同时切换到那个分支上,你可以运行一个带有 -b
参数的 git checkout
命令
$ git checkout -b bug1
Switched to a new branch 'bug1'
git checkout -b <branch name> <remote branch>(从远程分支创建并切换分支)
$ git checkout -b master1 origin/master
Switched to a new branch 'master1'
Branch master1 set up to track remote branch master from origin.
git merge <branch name>(分支合并)
我们想将出现分叉提交的分支整合在一起时,可以使用合并(merge)操作来完成。
Git 会使用两个分支的末端所指的快照以及这两个分支的工作祖先,做一个简单的三方合并。
$ git merge hotfix
快进合并(fast-forward) 当你试图合并两个分支时,如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候,只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”。 master只要向前推进就可以完成与iss53的合并,所以会使用快进合并。 |
遇到冲突时的分支合并
有时候合并操作不会如此顺利。 如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们。在合并它们的时候就会产生合并冲突。
解决冲突步骤:
1、需要手动解决冲突并标记已解决。
$ git add README.md
2、需要自己提交新的合并提交。
$ git commit
git rebase <branch name>(变基)
你可以提取在一个分支中引入的补丁和修改,然后在另一个分支的基础上应用一次。 在 Git 中,这种操作就叫做 变基。
Git变基时我们要分清,那个分支产生了补丁,那个分支是基底分支。
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: experiment
上例的当前分支(experiment)为补丁分支,rebase后面跟基底分支(master)。也就是说用experiment分支的提交创建补丁,在master分支上重新执行一遍。
从上图可以看出,分叉提交C4不见了,在C3后面重新提交了C4'。master基底分支指针不移动,experiment补丁分支指针指向C4'。
最后如果我们想要让master分支指针也指向最新提交C4',我们可以切换到master分支执行快进合并(fast-forward)。
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.(use "git push" to publish your local commits)$ git merge experiment
Updating 4f3f69a..373256b
Fast-forwardREADME.md | 3 ++-1 file changed, 2 insertions(+), 1 deletion(-)
git rebase --onto <base branch> [<upstream> [<branch>]](指定补丁分支变基)
我们可以指定补丁分支变基到基底分支上。
$ git rebase master experiment
First, rewinding head to replay your work on top of it...
Applying: experiment
还有一种更加复杂的用法。从master分支创建server分支,从server分支创建client分支。
如果我们想将client相对于server的不同提交变基到,master上我们可以这样使用。
$ git rebase --onto master server client
git rebase (--continue | --abort | --skip)(变基继续、终止、跳过)
在变基时如果发现补丁分支快照与基底分支快照存在冲突,变基会停止并且要求手动解决冲突。
变基停止时我们可以使用--continue | --abort | --skip参数来控制变基行为。
$ git rebase --continue
处理完冲突后使用此命令继续变基
$ git rebase --abort
放弃本次变基,还原成变基之前的样子
$ git rebase --skip
放弃补丁版本快照,继续使用基底版本快照。
git rebase -i (交互式变基)
交互式变基使用多次提交,重新建立提交。提交重建范围为没有push到远程分支的提交。
$git rebase -i
现在我们要对每次提交设置命令。一般的合并我们会将第一次提交选择为pick而后面的提交选择为squash。这样就会用所有的提交生成一次新的提交。
pick 4f3f69a experiment
pick 373256b experiment
pick 3258dad experiment
pick 167f684 experiment
pick cd871a6 experiment
pick d06c0a0 experiment
pick 9f3e252 experiment# Rebase 1221f68..9f3e252 onto 1221f68 (12 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
然后系统提示重新编辑提交说明。(被合并的提交说明会默认按顺序添加)
最后我们使用git log查看提交日志发现已经剩下一次提交了。
git rebase -i HEAD^^^(交互变基指定提交次数)
我们在进行交互式变基的时候可以指定变基提交的次数。HEAD参数后面每增加一个“^”符号代表向后提取一次分支。
$ git rebase -i HEAD^^^^^
这个命令代表从当前提交向后获取5次提交进行交互式变基。