Git版本控制 —— 经常使用命令目录

本文使用命令和命令的基本含义做为标题,旨在快速查找经常使用命令。git

 

环境配置

git config(配置文件设置)

Git 自带一个 git config 的工具来帮助设置配置文件。github

这些变量存储在三个不一样的位置:web

/etc/gitconfig 文件: 包含系统上每个用户及他们仓库的通用配置。 若是使用带有 --system选项的 git config 时,它会今后文件读写配置变量。shell

$ git config --system

~/.gitconfig 或 ~/.config/git/config 文件:只针对当前用户。 能够传递 --global 选项让 Git 读写此文件。数据库

$ git config --global

当前使用仓库的 Git 目录中的 config 文件(就是 .git/config):针对该仓库。能够传递 --local 选项让 Git 读写此文件。服务器

$ git config --local

咱们也能够不加参数表明从全部配置文件读写文件。app

$ git config

每个级别覆盖上一级别的配置,覆盖关系为local > global > system.ssh

下面举个例子:maven

-- 查看系统配置文件
$ 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_file

nothing 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.md

no 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 -s
 M 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 将每一个提交放在一行显示,查看的提交数很大时很是有用。 另外还有 shortfull 和 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] experiment
 Date: Mon Apr 16 10:48:55 2018 +0800
 2 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 branch
  dev_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 生产环境修改一个bug
  dev_5.2 fe13e9b [ahead 5] 生产环境修改一个bug
  master  fe13e9b [ahead 5] 生产环境修改一个bug

git branch -vv (查看分支附带跟踪分支)

从远程分支建立的本地分支,都会自动建立一个跟踪分支来维护本地分支与远程分支的对应关系。

咱们在pull或push代码时就会与对应的远程分支进行交互。

$ git branch -vv
* bug1    fe13e9b 生产环境修改一个bug
  dev_5.2 fe13e9b [origin/dev_5.2: ahead 5] 生产环境修改一个bug
  master  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
* bug1
  dev_5.2
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/dev_5.2
  remotes/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 就无法干净的合并它们。在合并它们的时候就会产生合并冲突。

解决冲突步骤:

一、须要手动解决冲突并标记已解决。

$ git add README.md

二、须要本身提交新的合并提交。

$ 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-forward
 README.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次提交进行交互式变基。

相关文章
相关标签/搜索