首页 > 学院 > 开发设计 > 正文

Git权威指南--穿错历史

2019-11-10 19:47:21
字体:
来源:转载
供稿:网友

0.查看版本库最新五次提交

$ git log --stat --oneline -5e2609ca 加结束标志 test_git.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)1f5c128 此处省略一万字 test_git.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)306b97b 增加修改时间 test_git.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)0c30d3e 增加修改人 test_git.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)07cab98 新增测试文件 test_git.txt | 1 + 1 file changed, 1 insertion(+)将最近两次提交合二为一,并把提交说明改为“增加修改时间......”

1.使用--soft 参数 调用重置命令,回到最近两次提交之前

$ git reset --soft HEAD^^2.查看版本库最新提交

$ git log -1commit 306b97b5dc629cb428d664c50f31f7815ad370f0Author: yinnana <nanayin@creditease.cn>Date:   Wed Feb 8 13:14:10 2017 +0800    增加修改时间3.执行提交操作,即完成最新两个提交压缩为一个提交的操作

$ git commit -m "增加修改时间......"[master 060a9f4] 增加修改时间...... 1 file changed, 3 insertions(+), 1 deletion(-)4.查看提交日志,验证

$ git log --stat --oneline -5060a9f4 增加修改时间...... test_git.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)306b97b 增加修改时间 test_git.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)0c30d3e 增加修改人 test_git.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)07cab98 新增测试文件 test_git.txt | 1 + 1 file changed, 1 insertion(+)66a5a9b modify test.txt test.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)

3.回到未来

涉及到的:拣选操作、变基操作、交互式变基操作

3.1  去除提交 D

0)对提交进行标识

$ git tag F$ git tag E HEAD^$ git tag D HEAD~2$ git tag C HEAD~3$ git tag B HEAD~4$ git tag A HEAD~5通过日志,可以看到被标记的六个提交

$ git log --oneline --decorate -62cbfc1b (HEAD -> master, tag: F) 添加正文e869230 (tag: E) 编辑文本内容6080809 (tag: D) 删除 注意事项!!f94e582 (tag: C) 注意事项1af8a1c5 (tag: B) 添加 注意事项060a9f4 (tag: A) 增加修改时间......

1)执行git checkout ,暂时将HEAD头指针切换到C(切换过程中显示出于非跟踪状态的警告)

$ git checkout CNote: checking out 'C'.You are in 'detached HEAD' state. You can look around, make experimentalchanges and commit them, and you can discard any commits you make in thisstate without impacting any branches by performing another checkout.If you want to create a new branch to retain commits you create, you maydo so (now or later) by using -b with the checkout command again. Example:  git checkout -b <new-branch-name>HEAD is now at f94e582... 注意事项1
$ git log --oneline --decorate -6f94e582 (HEAD, tag: C) 注意事项1af8a1c5 (tag: B) 添加 注意事项060a9f4 (tag: A) 增加修改时间......306b97b 增加修改时间0c30d3e 增加修改人07cab98 新增测试文件

2)执行拣选操作将E提交在当前HEAD上重放。

因为E和master^显然指向同一指向,因此可以用如下语法。

$ git cherry-pick master^[detached HEAD d8862cb] 编辑文本内容 Date: Wed Feb 8 13:32:28 2017 +0800 1 file changed, 1 insertion(+), 1 deletion(-)

3)执行拣选操作将F提交在当前HEAD上重放

F和master指向同一指向

$ git cherry-pick master[detached HEAD 5883cdd] 添加正文 Date: Wed Feb 8 13:33:14 2017 +0800 1 file changed, 3 insertions(+)

4)通过日志看到D不存在了

$ git log --oneline --decorate -65883cdd (HEAD) 添加正文d8862cb 编辑文本内容f94e582 (tag: C) 注意事项1af8a1c5 (tag: B) 添加 注意事项060a9f4 (tag: A) 增加修改时间......306b97b 增加修改时间

5)通过日志可以看出,最近两次提交的原始创作日期(AuthorDate)和提交日期(CommitDate)不同。

AuthorDate是拣选提交的原始更改时间,CommitDate是拣选操作的时间

$ git log --PRetty=fuller --decorate -3commit 5883cddb3b5d8f5a88aec7eb1ce1ff616a9606e4 (HEAD)Author:     yinnana <nanayin@creditease.cn>AuthorDate: Wed Feb 8 13:33:14 2017 +0800Commit:     yinnana <nanayin@creditease.cn>CommitDate: Wed Feb 8 14:00:40 2017 +0800    添加正文commit d8862cbb1913ced14ce4c9441204019965751567Author:     yinnana <nanayin@creditease.cn>AuthorDate: Wed Feb 8 13:32:28 2017 +0800Commit:     yinnana <nanayin@creditease.cn>CommitDate: Wed Feb 8 13:58:16 2017 +0800    编辑文本内容commit f94e582809f7cc05bf5e8c9950dd32ebc4ac6ac4 (tag: C)Author:     yinnana <nanayin@creditease.cn>AuthorDate: Wed Feb 8 13:30:53 2017 +0800Commit:     yinnana <nanayin@creditease.cn>CommitDate: Wed Feb 8 13:30:53 2017 +0800    注意事项16)将master分支重置到新的提交ID(5883cdd)上

下面的切换操作使用了reflog的语法,即HEAD@{1}相当于切换回master分支前的HEAD指向

$ git checkout masterWarning: you are leaving 2 commits behind, not connected toany of your branches:  5883cdd 添加正文  d8862cb 编辑文本内容If you want to keep them by creating a new branch, this may be a good timeto do so with: git branch <new-branch-name> 5883cdd
$ git reset --hard HEAD@{1}HEAD is now at 5883cdd 添加正文

比较

2cbfc1b (HEAD -> master, tag: F) 添加正文e869230 (tag: E) 编辑文本内容6080809 (tag: D) 删除 注意事项!!f94e582 (tag: C) 注意事项1af8a1c5 (tag: B) 添加 注意事项060a9f4 (tag: A) 增加修改时间......后**********5883cdd (HEAD -> master) 添加正文d8862cb 编辑文本内容f94e582 (tag: C) 注意事项1af8a1c5 (tag: B) 添加 注意事项060a9f4 (tag: A) 增加修改时间......306b97b 增加修改时间

3.2 合并 提交CD

0)将master分支重新置回到提交F上
$ git checkout masterAlready on 'master'
$ git reset --hard FHEAD is now at 2cbfc1b 添加正文
$ git log --oneline --decorate -62cbfc1b (HEAD -> master, tag: F) 添加正文e869230 (tag: E) 编辑文本内容6080809 (tag: D) 删除 注意事项!!f94e582 (tag: C) 注意事项1af8a1c5 (tag: B) 添加 注意事项060a9f4 (tag: A) 增加修改时间......1)暂时将HEAD头指针切换到D
$ git checkout DNote: checking out 'D'.You are in 'detached HEAD' state. You can look around, make experimentalchanges and commit them, and you can discard any commits you make in thisstate without impacting any branches by performing another checkout.If you want to create a new branch to retain commits you create, you maydo so (now or later) by using -b with the checkout command again. Example:  git checkout -b <new-branch-name>HEAD is now at 6080809... 删除 注意事项!!2)悔棋两次,以便将C和D融合
$ git reset --soft HEAD^^
$ git log --oneline --decorate -6af8a1c5 (HEAD, tag: B) 添加 注意事项060a9f4 (tag: A) 增加修改时间......306b97b 增加修改时间0c30d3e 增加修改人07cab98 新增测试文件66a5a9b modify test.txt3)提交,重用提交C的提交说明
$ git commit -C C[detached HEAD 670829a] 注意事项1 Date: Wed Feb 8 13:30:53 2017 +0800 1 file changed, 1 insertion(+), 1 deletion(-)4)执行拣选操作将E提交在当前HEAD上重放
$ git cherry-pick E[detached HEAD 133d8cf] 编辑文本内容 Date: Wed Feb 8 13:32:28 2017 +0800 1 file changed, 1 insertion(+), 1 deletion(-)5)执行拣选操作将F提交在当前HEAD上重放
$ git cherry-pick F[detached HEAD 2642edf] 添加正文 Date: Wed Feb 8 13:33:14 2017 +0800 1 file changed, 3 insertions(+)6)通过日志看到提交C和D融合,所以在日志中看不到C的标签
$ git log --oneline --decorate -62642edf (HEAD) 添加正文133d8cf 编辑文本内容670829a 注意事项1af8a1c5 (tag: B) 添加 注意事项060a9f4 (tag: A) 增加修改时间......306b97b 增加修改时间7)将master分支指向新的提交ID(2642edf)下面的切换操作使用了reflog的语法,即HEAD@{1}相当于切换回master分支前的HEAD指向
$ git checkout masterWarning: you are leaving 3 commits behind, not connected toany of your branches:  2642edf 添加正文  133d8cf 编辑文本内容  670829a 注意事项1If you want to keep them by creating a new branch, this may be a good timeto do so with: git branch <new-branch-name> 2642edfSwitched to branch 'master'
$ git reset --hard HEAD@{1}HEAD is now at 2642edf 添加正文
$ git log --oneline --decorate -62642edf (HEAD -> master) 添加正文133d8cf 编辑文本内容670829a 注意事项1af8a1c5 (tag: B) 添加 注意事项060a9f4 (tag: A) 增加修改时间......306b97b 增加修改时间

3.3 rebase 变基操作

0)将master分支重新置回到提交F上
$ git checkout masterAlready on 'master'
$ git reset --hard FHEAD is now at 2cbfc1b 添加正文git rebase 可以实现将指定范围的提交 嫁接到另一个提交之上命令格式:用法1:git rebase --onto <newbase><since> <till>用法2:git rebase --onto <newbase><since>用法3:git rebase <since><till>用法4:git rebase  <since>用法5:git rebase  -i ...用法6:git rebase --continue用法7:git rebase --skip用法8:git rebase --abort

用法6是在变基遇到冲突而暂停的情况下,先完成冲突解决(添加到暂存区,不提交),然后在恢复变基操作的时候使用该命令。

用法7是在变基遇到冲突而暂停的情况下,跳过当前提交的时候使用。

用法8是在变基遇到冲突而暂停的情况下,终止变基操作,回到之前的分支时候使用。

用法1为例,其用法如下:

git rebase --onto <newbase><since> <till>

1.首先会执行 git checkout 切换到 <till>

如果<till>指向 的不是一个分支(如master),则变基操作是在 detached HEAD(分离头指针)状态进行的,

当变基结束后,像上述3.1那样,对master分支执行重置以实现变基结果在分支中生效。

2.将<since>...<till>所标识的提交范围写到一个临时文件中

包括<till>的所有历史提交排除<since>及<since>的历史提交后形成的版本范围

3.将当前分支强制重置(git reset --hard)到<newbase>

相当于执行git reset --hard <newbase>

4.从保存在临时文件中的提交列表中,将提交逐一按顺序重新提交到重置之后的分支上

5.如果遇到提交已经在分支中包含,则跳过该提交

6.如果在提交过程中遇到冲突,则变基过程暂停。

用户解决冲突后,执行 git rebase --continue 继续变基操作,

或者执行 git rebase --skip跳过此提交,

或执行 git rebase --abort就此终止变基操作切换到当前变基前的分支上

很显然为了执行将E和F提交跳过提交D,嫁接到提交C上,可以执行如下变基命令:

git rebase --onto C E^ F

因为 E^ 等价于D,并且F和当前HEAD的指向相同,因此可以这样:

git rebase --onto C D

$ git status -s -b## master
$ git log --oneline --decorate -62cbfc1b (HEAD -> master, tag: F) 添加正文e869230 (tag: E) 编辑文本内容6080809 (tag: D) 删除 注意事项!!f94e582 (tag: C) 注意事项1af8a1c5 (tag: B) 添加 注意事项060a9f4 (tag: A) 增加修改时间......


上一篇:Database,Uva1592

下一篇:集合面试

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表